やりたいこと
C言語をそこそこ学んだ後、C++を学び始めたものです。
C++の勉強として、電話帳の動きを模したプログラムを作成しています。
重複した処理が多いため、共通部分を抽象化したいです。
関数ポインタを渡すことで、きれいに書けると思っていますがうまくいきません。
クラス定義
cpp
1class Contact 2{ 3 public: 4 void setFirstName(std::string s) { firstName = s; } 5 void setLastName(std::string s) { lastName = s; } 6 void setNickname(std::string s) { nickname = s; } 7 void setphoneNumber(std::string s) { phoneNumber = s; } 8 void setDarkestSecret(std::string s) { darkestSecret = s; } 9 10 std::string getFirstName() const { return firstName; } 11 std::string getLastName() const { return lastName; } 12 std::string getNickname() const { return nickname; } 13 std::string getPhoneNumber() const { return phoneNumber; } 14 std::string getDarkestSecret() const { return darkestSecret; } 15 private: 16 std::string firstName; 17 std::string lastName; 18 std::string nickname; 19 std::string phoneNumber; 20 std::string darkestSecret; 21}; 22 23class Phonebook 24{ 25 public: 26 void add(int i); 27 void exit(); 28 29 private: 30 Contact contact[8]; 31};
クラス関数の定義
ここの繰り返し処理を関数ポインタを使うことで短く書きたいです。
cpp
1void Phonebook::add(int i) 2{ 3 std::string line; 4 5 // first nameの入力 6 std::cout << "first name : "; 7 std::getline(std::cin, line); 8 while (line.empty()) 9 { 10 std::cout << "first name : "; 11 std::getline(std::cin, line); 12 } 13 contact[i].setFirstName(line); 14 15 // last nameの入力 16 std::cout << "last name : "; 17 std::getline(std::cin, line); 18 while (line.empty()) 19 { 20 std::cout << "last name : "; 21 std::getline(std::cin, line); 22 } 23 contact[i].setLastName(line); 24}
試したこと
追記 2021/07/05 17:59
以下の関数を定義し、呼び出してみましたが、うまく行きません。
cpp
1void addItem(int i, void (Contact::*fn)(std::string), std::string s) 2{ 3 std::string line; 4 5 std::cout << s; 6 std::getline(std::cin, line); 7 while (line.empty()) 8 { 9 std::cout << s; 10 std::getline(std::cin, line); 11 } 12 fn(line); 13} 14 15void Phonebook::add(int i) 16{ 17 Contact tmp = getContact(i); 18 addItem(i, Contact::setFirstName, "frist name : "); 19 20}
このエラーが出ます。
terminal
1❯ g++ main.cpp sample.cpp 2sample.cpp:20:7: error: called object type 'void (Contact::*)(std::string)' is not a function or function pointer 3 fn(line); 4 ~~^ 5sample.cpp:26:25: error: call to non-static member function without an object argument 6 addItem(i, Contact::setFirstName, "frist name : "); 7 ~~~~~~~~~^~~~~~~~~~~~ 82 errors generated.
よろしくお願いします。
環境
C++11
❯ g++ --version Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1 Apple clang version 12.0.5 (clang-1205.0.22.11) Target: x86_64-apple-darwin20.5.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin ## コンパイル方法 ❯ g++ main.cpp sample.cpp
追記 2021/07/05 19:00
templateを使わない縛りで書いているので、std::function<void(std::string)>を使用して実現したいです。
cpp
1void Phonebook::addItem(int i, std::function<void(std::string)> fn, std::string s) 2{ 3 std::string line; 4 5 std::cout << s; 6 std::getline(std::cin, line); 7 while (line.empty()) 8 { 9 std::cout << s; 10 std::getline(std::cin, line); 11 } 12 fn(line); 13} 14 15void Phonebook::add(int i) 16{ 17 addItem(i, &getContact(i).setFirstName, "frist name : "); 18}
以下のエラーが出ます。
terminal
1❯ g++ -std=c++11 main.cpp sample.cpp && ./a.out 2sample.cpp:24:16: error: cannot create a non-constant pointer to member function 3 addItem(i, &getContact(i).setFirstName, "frist name : "); 4 ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 51 error generated.
&を取ってもエラーが出て実行できませんでした。
terminal
1❯ g++ -std=c++11 main.cpp sample.cpp && ./a.out 2sample.cpp:24:30: error: reference to non-static member function must be called 3 addItem(i, getContact(i).setFirstName, "frist name : "); 4 ~~~~~~~~~~~~~~^~~~~~~~~~~~ 51 error generated.
回答5件
あなたの回答
tips
プレビュー