クラス名&メンバ関数名とは何ですか?

このQ&Aのポイント
  • Windowsのタスクから起動し、シリアル接続した組み込み用マイコン(PIC)に、コマンドを送るプログラムを作るために、C++を学習中です。
  • C++におけるクラス名&メンバ関数名の記述について、理解できない部分があります。
  • 質問のタイトル「クラス名&メンバ関数名/クラス名 & メンバ関数名」の意味について教えてください。
回答を見る
  • ベストアンサー

意味を教えてください:クラス名& メンバ関数名/クラス名 & メンバ関数名

Windowsのタスクから起動し、シリアル接続した組み込み用マイコン(PIC)に、コマンドを送るプログラムを作ろうと、勉強中です。シリアル通信ActiveXが全てのPCで使えるという状況では無いため、どうせAPIを使うなら,この機会にc++を勉強しようと考えました。当方のスキルはPIC用のCで、ちょっとした制御が出来る程度です(PCで使用しているのは主にVBAですが、毎回Excel起動では重すぎて...)。軽く・小さくしてやろうと、VC++2005Express + WIN32SDKを使っています。主にWEBで勉強させていただいておりますが、参考に海外サイトからダウンロードした、シリアル通信用クラスがさっぱり解読できず困っています。(VBやVBAでのクラスの使い方は一応知っています)。本質問のタイトル付けにも困りましたが、適当なキーワードが分からず、WEB検索もうまくいきませんでした。 1.COMPortという名前をつけたクラスのヘッダーファイルに private: COMPort (const COMPort &); COMPort& operator= (const COMPort &); とありますが、既にここから分かりません。二つの文はどういう意味なのでしょうか? 2.クラスの.cppファイルに、 //こちらは頭のCOMPortと&の間にスペース無し COMPort& COMPort::setState () { if (!SetCommState ( (HANDLE) thePortHandle, (LPDCB) theDCB)) { throw runtime_error ("COMPort: could not modify serial port state."); } return *this; } というのとか、 //こちらは頭のCOMPortと&の間にスペースあり COMPort & COMPort::write ( const char inChar ) { char buffer = inChar; DWORD charsWritten = 0; if ( !WriteFile ( (HANDLE(thePortHandle)), &buffer, sizeof(char), &charsWritten , NULL)) { throw runtime_error ("COMPort: write failed."); } return *this; } があって、やっている事自体はAPIを実行しているだけと思いますが、質問タイトルの”クラス名& メンバ関数名/クラス名 & メンバ関数名”という記述はどういう意味なのでしょうか?教えていただけると幸いです。

質問者が選んだベストアンサー

  • ベストアンサー
  • Werner
  • ベストアンサー率53% (395/735)
回答No.2

> COMPort (const COMPort &); はコンストラクタ(コピーコンストラクタ)の宣言 > COMPort& operator= (const COMPort &); は代入演算子の宣言です。 これらの宣言をprivateで行っているということは コピーコンストラクタや代入演算子を使用できないようにしていると言うことです。 オブジェクト(インスタンス)のコピーを禁止するための記述だと思われます。 C++編(言語解説) 第16章 コピーコンストラクタ http://www.geocities.jp/ky_webid/cpp/language/016.html クラスのコピー禁止のテクニックについては 以下のページの「コピーの禁止」に少し書かれてました。 Language C++ Seminar/Chapter 2/Section 4 http://www.futatsugi.net/develop/cpp/cpp00204.html

mitarashi
質問者

お礼

目的は理解できた様な気がします。ポインタをメンバーに持つクラスを単純に複写、代入してしまうと、複数のクラスから同じアドレスにアクセスしてしまう事になるのを防止するためというところでしょうか。VBに比べるとコードが読みにくいのと(c/c++に慣れた人はVBのコードがうるさい等と思うのかも)、選択肢の多さに戸惑っておりますが、何とかモノにしたいと思います。一旦閉じて勉強させていただきます。 ありがとうございました。

その他の回答 (1)

  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

その&は参照です。 C++の勉強してるならどこかで目にしていてもおかしくなさそうなものですが。 とりあえず"C++ 参照"で検索して見つけたページを載せておきます。 http://www.geocities.jp/ky_webid/cpp/language/015.html なお、スペースはあってもなくても同じ。

mitarashi
質問者

お礼

深夜にもかかわらず、早速のご回答ありがとうございました。VBでいうところのByRefなのですね。(VBのクラスなら意識しないで良い部分の様な。)ご紹介いただいたサイトは知っていたのですが、つまみ食いの勉強でそこまでたどり着いていませんでした。Object自体への参照を戻す関数であるという事は理解できました。 下記については相変わらず理解不能ですので、意味を教えていただけないでしょうか。よろしくお願いします。 >1.COMPortという名前をつけたクラスのヘッダーファイルに >private: >COMPort (const COMPort &); >COMPort& operator= (const COMPort &);

関連するQ&A

  • C++言語 メンバ関数

    何気なく使用しているクラスのメンバ関数、これの中身が実際どうなってるか知りたいです。大別して2種類に分かれますので以下の2つを 教えて下さい。また詳しく載っているサイトなどあれば教えて下さい。 1,stringクラスMid(int start,int length関数と operator関数+について class String{ char *p; char *q; public: //各定義 }; String String::Mid(int start,int length) const { // } String String::operator+(const String&s)const{ return String(p+s.q+s.p); } 最初の方はイメージもつかず、2つめのほうはポインタに ポインタを加えようとしましたとでます。 教えて下さい。

  • 関数名の名前の衝突について。

    こんにちは。 関数名の名前の衝突で困っています。 以下のような感じで名前空間でUNICODEでマルチバイト版とで定義しています。 Win32APIのGetFileSize関数を例に説明します。 Win32APIのGetFileSize関数はファイルハンドルを指定しなければいけないので 直接ファイル名からファイルサイズを取得できるように同じ名前の関数を 名前空間で区切って以下のようにしました。 ---------------- Foo.h -------------- #include <windows.h> namespace Foo { #ifdef UNICODE     #define GetFileSize GetFileSizeW #else     #define GetFileSize GetFileSizeA #endif // !UNICODE     DWORD GetFileSizeW( wchar_t* const szFilename ){ return 0 ;}     DWORD GetFileSizeA( char* const szFilename ){ return 0 ;} } ---------------- Foo.h -------------- 上記の関数はちゃんと動作することは確認できましたが、本来のWin32APIの DWORD GetFileSize( HANDLE hFile, LPDWORD lpFileSizeHigh ) を ---------------- main.cpp -------------- #include <windows.h> #include "Foo.h" void func( HANDLE hFile ) {     DWORD dwFilesize = ::GetFileSize( hFile, NULL ) ; } ---------------- main.cpp -------------- 上記のように利用しようとすると、 error C2039: 'GetFileSizeW' : '`global namespace'' のメンバではありません。 error C3861: 'GetFileSizeW': 識別子が見つかりませんでした というエラーが出てきてしまいます。 これを解決するためにはUNICODEでマルチバイト版とで再定義してしまっている #defineの部分を削除するしかないのでしょうか? もし解決方法がありましたら教えていただけないでしょうか?

  • char** buffer (このような2重の**の意味について)

    私は現在C++のプログラミングを学習しています。 C++の教本(SoftbankCreative 高橋麻奈著 やさしいC++) 自体は読み終え、今現在別のプログラムの本を読んでいるのですが、 わからない表記があり、 またネットでどのように(何という名前で)検索していいかわからないのでこちらで質問させて頂きます。 (char* buffer などであれば「ポインタ」とかで検索すれば出るのですが…、char**のように2重になってるのは引っ掛かりませんでした。) たとえば、 void readFile( char** buffer, int* size, const char* filename ); このような場合、 char** buffer はどういう事なのでしょうか? この書き方の名前等はありますか?(char* buffer だと ポインタ のように) あるいは、基本的なC++の本に載っている知識の組み合わせで理解できるものなのでしょうか? ネットのC++勉強サイトや、ヒントでいいので教えて頂きたいです。 必要ないかもしれませんが、私がつまった所に関連するコードを載せておきます。 void readFile( char** buffer, int* size, const char* filename );  ~~~ (mainLoop()という関数内) const char* filename = "stageData.txt"; char* stageData; int fileSize; readFile( &stageData, &fileSize, filename );  ~~~ void readFile( char** buffer, int* size, const char* filename ){ ifstream in( filename, ifstream::binary ); if ( !in ){ *buffer = 0; *size = 0; }else{ in.seekg( 0, ifstream::end ); *size = static_cast< int >( in.tellg() ); in.seekg( 0, ifstream::beg ); *buffer = new char[ *size ]; in.read( *buffer, *size ); } } 途中で、 char* stageData; とし、 readFile( &stageData, のように放り込んでいるので、 ポインタのその更にポインタ、みたいな感じでしょうか? であればあえて2重にする意味がよくわからないです。 よろしくお願い致します。

  • constのついたメンバ関数

     こんにちは。 C++を勉強しているのですが疑問に思ったことがあります。 const指定したメンバ関数にメンバ変数の変更をすることはエラーになるはずなんですが、 下記にある(*m_pRefCnt)++; はコンパイルが通るようです。 なぜこの一文だけ通るのでしょうか? 以下にソースを添付しておきます。 #include <iostream> class hogeClass { private: int* m_pRefCnt; int val; void AddRef() const { (*m_pRefCnt)++; // これはOK? val = 100; // これは駄目 } void Release() { } public: explicit hogeClass(char* src = NULL) : val(0) { } int& GetRefCnt() { return *(m_pRefCnt); } virtual ~hogeClass() { Release(); } }; int main() { int c = 435, k = 222; using namespace std; hogeClass a; getchar(); return 0; } 分かる人がいたらよろしくお願いします。

  • C/C++関数間でのStringクラスの扱い

    以下のようなコードを実行してみましたが思い通りに動いてくれません. "sample"という文字列がstrへとコピーされると思ったのですが. stringクラスのc_str()メソッドはconst char*だと言っているので無理矢理キャストしたのが原因でしょうか.stringクラスは記憶領域を自動で変更してくれるのではないのですか.それともこの挙動は仕様ですか. -------- 以下コード -------- #include <iostream> #include <string> using namespace std; int func(char *); int main(void) {     string str("");     func((char *)str.c_str());     cout << "String: " << str << endl;     return EXIT_SUCCESS; } int func(char *buf) {     buf = "sample";     return 0; } -------- 以上コード --------

  • C++のクラス内のchar *strについて

    初歩的な質問で申し訳ありませんが、いまC++を勉強していてわからないところがあったので質問させていただきます。以前C言語を少ししていたのでアスタリスクがポインタのことを指しているというのはわかるのですがC++でクラスを扱うとなったときなぜクラス内でconst char *strと変数の前にアスタリスクがつくのかがわかりません。ためしにアスタリスクを外してコンパイルすると4つくらいエラーが出てきて読み取り専用メンバへの代入とかchar* から char への不正(?)な変換とか出てくるのですが肝心のアスタリスクをつける意味が結局わかりませんでした。なので誰か教えてください。

  • C++の関数テンプレートで分からないところがあります。

    C++の関数テンプレートで分からないところがあります。 C++の入門書を読んで勉強しているのですが、その演習問題(答えはついてないです)で、以下のような問題がありました。 ----------------------------------------------------- 配列の全要素の最小値を求める関数テンプレートを作成せよ。 teplate <class Type> Type minof(const Type x[], int n); という形で作ること。 なお、最も小さい文字列を求められるようにするために、const char *型に明示的に特殊化したものも合わせて作成すること。 ------------------------------------------------ という問題なのですが、これにたいして僕は以下のように答えました。ヘッダのインクルードなどは省きます。 template<class Type> Type minof(const Type x[], const int n) {     int min = 0;     for(int i = 1; i < n; i++)         if(x[min] < x[i])             min = i;     return x[min]; } template<> const char* minof<const char *>(const char x[][64], const int n) {     int min = 0;     for(int i = 1; i < n; i++)         if(strcmp(x[min], x[i]) < 0)             min = i;     return x[min]; } int main() {     const int n = 5;     int a[n];     char s[n][64];     for(int i = 0; i < n; i++){         cout << i + 1 << "番目---";         cin >> a[i];     }     cout << "文字列\n";     for(int i = 0; i < n; i++){         cout << i + 1 << "番目---";         cin >> s[i];     }     cout << "整数の最小値---" << minof(a, n) << "です\n";     cout << "文字列の最小値---" << minof<const char *>(s, n) << "です\n"; } これをコンパイルすると、エラーで 明示的な特殊化; 'const char *minof<const char*>(const char [][64],const int)' は関数テンプレートの特殊化ではありません と 'minof' : 1 番目の引数を 'char [5][64]' から 'const char *const []' に変換できません。 とでてしまいます。 色々探してみたのですが、解決できませんでした・・。 特に最初のほうのエラーがよくわかりません。ちゃんと特殊化してる気はするのですが・・。 間違っている箇所の正当を載せていただけるとわかりやすくて、ありがたいです。 よろしくお願いします!

  • 仮想基底クラスをもつクラスの代入演算2

    <仮想基底クラスをもつクラスの代入演算>の続きですが、結局、assign のようなものを作って、以下のように書くのが一番いいのでしょうか。。。 ====(一応、自己代入も考慮して書くと^^) #include <algorithm> struct X { int x; X &assign(const X &z, bool top) { if (this != &z) x = z.x; return *this; } X &operator=(const X &z) { return assign(z, true); } }; struct A : virtual X { int a; A &assign(const A &z, bool top) { if (this != &z) { if (top) X::assign(z, false); a = z.a; } return *this; } A &operator=(const A &z) { return assign(z, true); } }; struct B : virtual X { int b; B &assign(const B &z, bool top) { if (this != &z) { if (top) X::assign(z, false); b = z.b; } return *this; } B &operator=(const B &z) { return assign(z, true); } }; struct C : A, B { int c; C &assign(const C &z, bool top) { if (this != &z) { if (top) X::assign(z, false); A::assign(z, false); B::assign(z, false); c = z.c; } return *this; } C &operator=(const C &z) { return assign(z, true); } }; ==== ただ、<仮想基底クラスをもつクラスの代入演算>で、jacta さんが提示してくださった方法も、処理量は増えますが、アロケートする必要があるポインタなどのデータメンバのアロケートやデリートする処理コードをコンストラクタに集中できるので、「コーディング量の減少・改変の際の修正し忘れの可能性を低くできる」というメリットがあると思います。ハンドルクラスやコンテナクラスを実装する際は、swap() 機能が必要となると考えられるので、jacta さんのコピーコンストラクタでコピー代入を実装する方法の方がいいのかとも思います。 みなさん、どう思われますか? また、そのほかに、効果的なテクニックがあれば、ぜひ、ご教示ください。

  • c++ クラスに関してです。

    うまくクラス同士を連動させることができなくてエラーが出てしまいます。 どこが間違えているのかアドバイスくださると助かります。 #ifndef H22_H_ #define H22_H_ #include <string> #include "account.h" class Bank { public: Bank(); void deposit(double amount, const std::string& accountType); void withdraw(double amount, const std::string& accountType); void transfer(double amount, const std::string& accountType); double getBalance() const; double getSavingsBalance() const; double getCheckingBalance() const; private: Account checking, savings; }; #endif #ifndef ACCOUNT_H #define ACCOUNT_H #include <string> #include "account.h" class Account{ public: Account(); Account(double &amout); double deposit(double amount); double getBalance() const; double withdraw(double amount); double balance; private: }; #endif #include <iostream> #include "acount.h" using namespace std; Account::Account { balance = 0; } Account::Account(double amount) { balance = amount; } Account::double deposit() const { return balance; } Account::double getBalance(double balance) { balance += amount; return balance; } Account::double withdraw(double amount) { if(amount > balance) { balance -= 5; return balance; } elese { balance -= amount; return balance; }} h22.h の中身 #include <string> #include "h22.h" #include "account.h" #include <stdexcept> using namespace std; Bank::Bank() { Account checking; Account saving; } void Bank::deposit(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") throw invalid_argument("Does not compute"); else if(accountType == "S") savings.balance += amount; else if(accountType == "C") checking.balance += amount; } void Bank::withdraw(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") throw invalid_argument("Does not compute"); else if(accountType == "S") savings.balance -= amount; else if(accountType == "C") checking.balance -= amount; } void Bank::transfer(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") { throw invalid_argument("Does not compute");} else if(accountType == "S") { savings.balance += checking.balance; savings.balance = 0;} else if(accountType == "C") { checking.balance += amount; checking.balance = 0;} } double Bank::getBalance() const { return getBalance(); } double Bank::getSavingsBalance() const { return savings.getBalance(); } double Bank::getCheckingBalance() const { return checking.getBalance(); } メイン.cpp http://pastebin.com/rQTj8xciです。 なにかヒントやアドバイスお願いします

  • ファイル名リストの置換処理

    以前、ファイルリストの取得について教えて頂きました。ありがとうございます。 取得したリストを文字列で入れ替えるにはどうすればよいでしょうか 例えば取得したリストの最初の位置の文字列dml[0]をEcoDataFileNameと置き換えたいです。 #include <Windows.h> #include <map> #include <vector> #include <string> #include <iostream> #include "time.h" using namespace std; bool operator<(const FILETIME& x, const FILETIME& y) { if ( x.dwHighDateTime < y.dwHighDateTime ) return true; if ( y.dwHighDateTime < x.dwHighDateTime ) return false; return x.dwLowDateTime < y.dwLowDateTime; } class DML_Backup { vector<string> files_; public: void search(const char* spec) { typedef multimap<FILETIME,string> map_type; map_type files; WIN32_FIND_DATAA find_data; HANDLE handle = FindFirstFileA(spec, &find_data); if ( handle != INVALID_HANDLE_VALUE) { do {   files.insert(map_type::value_type(find_data.ftLastWriteTime, find_data.cFileName)); } while ( FindNextFileA( handle, &find_data) ); FindClose(handle); } files_.clear(); for ( map_type::iterator iter = files.begin(); iter != files.end(); ++iter ) { files_.push_back(iter->second); } } string operator[](int inx) const { return files_.at(inx).c_str(); } int size() const { return files_.size(); } }; int main() { DML_Backup dml; char EcoDataFileName="MonJun131956122011.ecd"; dml.search("*.ecd"); }

専門家に質問してみよう