C++クラス定義の質問

このQ&Aのポイント
  • C++学習者です。Visual studio community 2015 を使っています。銀行口座を表す SavingsAccount というクラスを作り、添付のプログラムをコンパイルしようとしましたが、リンクエラーが発生しました。
  • エラーメッセージによると、未解決の外部シンボル annualInterestRate があるとのことです。値を代入しているのになぜ未解決なのでしょうか?どうすれば解決できるでしょうか?
  • 以下がクラス定義ヘッダーファイル、クラス関数定義ファイル、およびクライアントプログラムのコードです。
回答を見る
  • ベストアンサー

C++ クラス定義の質問

C++学習者です。Visual studio community 2015 を使っています。 銀行口座を表す SavingsAccount というクラスを作り、添付のプログラムをコンパイルしようとしましたが。以下のようなエラーメッセージが出てきました。 1>------ ビルド開始: プロジェクト:ConsoleApplication86, 構成:Debug Win32 ------ 1>savingsAccount.obj : error LNK2001: 外部シンボル ""private: static double SavingsAccount::annualInterestRate" (?annualInterestRate@SavingsAccount@@0NA)" は未解決です。 1>C:\Users\Shiro\documents\visual studio 2015\Projects\ConsoleApplication86\Debug\ConsoleApplication86.exe : fatal error LNK1120: 1 件の未解決の外部参照 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== ちゃんと値を代入しているのに、annualInterestRate が未解決とはどういうことなのでしょうか? 以下が、クラス定義ヘッダーファイル、クラス関数定義ファイル、クライアントプログラムです。どうかよろしくお願いいたします。 //**************************************** // クラス定義ヘッダーファイル //**************************************** #pragma once #ifndef SAVINGSACCOUNT_H #define SAVINGSACCOUNT_H class SavingsAccount { static double annualInterestRate; public: SavingsAccount(double); ~SavingsAccount(); static void modifyInterestRate(double); double calculateMonthlyInterest(); double getBalance() const; double getSavingsBalance() const; private: double balance; double savingsBalance; }; #endif //*************************************** // クラス関数定義ファイル //*************************************** // savingsAccount class member functions #include "stdafx.h" #include <iostream> using namespace std; #include "savingsAccount.h" double annualInterestRate = 0.03; SavingsAccount::SavingsAccount(double initialAmount) :balance(initialAmount) { savingsBalance = balance + calculateMonthlyInterest(); cout << "savings account with balance of " << balance << " and savings balance of " << savingsBalance << " has been constructed\n"; } SavingsAccount::~SavingsAccount() { cout << "savings account of the savings balance of " << savingsBalance << " has been destructed\n"; } void SavingsAccount::modifyInterestRate(double newRate) { annualInterestRate = newRate; } double SavingsAccount::getBalance() const { return balance; } double SavingsAccount::getSavingsBalance() const { return savingsBalance; } double SavingsAccount::calculateMonthlyInterest() { return balance * annualInterestRate / 12; } //******************************************** // クライアントプログラム //******************************************** // ConsoleApplication86.cpp : // class SavingsAccount driver program #include "stdafx.h" #include <iostream> using namespace std; #include "savingsAccount.h" int main() { SavingsAccount saver1(2000.00); SavingsAccount saver2(3000.00); cout << "original amount of saving for saver1 : " << saver1.getBalance() << " and savings with interest: " << saver1.getSavingsBalance() <<endl; cout << "----------------------------------\n"; cout << "original amount of saving for saver2 : " << saver2.getBalance() << " and savings with interest: " << saver2.getSavingsBalance() << endl; return 0; }

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

  • ベストアンサー
回答No.1

× double annualInterestRate = 0.03; ○ double SavingsAccount::annualInterestRate = 0.03;

papashiroSooke
質問者

お礼

早速に、明解なご回答を頂きまして、有難うございます。 ちゃんとコンパイルできました。

関連するQ&A

  • 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です。 なにかヒントやアドバイスお願いします

  • C++ クラスの作り方

    Windows10の上で、Visual Studio Community2015 を使ってC++を勉強中の者です。 Time クラスというのを定義して使おうとしましたが、クライアント側のプログラム作成中にエラーメッセージが出てきて、色々考えましたがどこが悪いのかわかりません。 プログラム自体は時刻を設定してそれを表示させるだけのものです。 詳しい方がいらっしゃいましたら、ご教授お願い致します。 問題のエラーメッセージ; "consoleApplication69.cpp" を作成中にエディターの中で、波型の赤線が出ているところにカーソルを持っていくと、次の3か所でそれぞれ次のようなエラーメッセージが出てきます。 (1) #include "time3.h" のところ: 「ソースファイルをひらけません。"time3.h"」 (2) 関数 incrementMinute( )のプロトタイプのところ:「不完全な型は使用できません。」 (3) 最初のパラメーター Time & のところ:「識別子 Time が定義されていません。」 以下に、 1: 私が作ったTimeクラスの定義のあるヘッダー "time3.h", 2: メンバー関数の定義ファイル "time3.cpp" 3:クライアント側プログラム "consoleApplication69.cpp" の3つのソースコードをコピーします。 "time3.cpp" については長いので、上の半分だけにしました。 ****************************************************** 1: "time3.h" ******************************************************** #pragma once // header file for Time class // time3.h #ifndef TIME3_H #define TIME3_H class Time { public: Time(int = 0, int = 0, int = 0); ~Time(); void setTime(int, int, int); void setHour(int); void setMinute(int); void setSecond(int); int getHour(); int getMinute(); int getSecond(); void printUniversal(); void printStandard(); private: int hour; int minute; int second; }; #endif *********************************************** 2: "time3.cpp" ************************************************ #include <iostream> #include <iomanip> #include <cstdlib> #include <ctime> #include <cmath> #include <cstring> #include "time3.h" using namespace System; using namespace std; Time::Time(int hr, int min, int sec) { setTime(hr, min, sec); } void Time::setTime(int hr, int min, int sec) { setHour(hr); setMinute(min); setSecond(sec); } void Time::setHour(int hr) { hour = (0 <= hr && hr <= 23) ? hr : 0; } void Time::setMinute(int min) { minute = (0 <= min && min <= 59) ? min : 0; } void Time::setSecond(int sec) { second = (0 <= sec && sec <= 59) ? sec : 0; } ********************************************************* 3: "consoleApplication69.cpp" ********************************************************* // ConsoleApplication69.cpp : メイン プロジェクト ファイルです。 #include "stdafx.h" #include <iostream> #include <iomanip> #include "time3.h" using namespace System; using namespace std; //prototype void incrementMinute(Time &, const int); int main() { Time t; t.setHour(2); t.setMinute(10); t.setSecond(30); cout << " current time is "; cout << setfill('0'); cout << setw(2) << t.getHour() << ":"; cout << setw(2) << t.getMinute() << ":"; cout << setw(2) << t.getSecond() << "\n"; return 0; } // function void incrementMinute(Time &tt, const int num) { // まだ未定義 } またソリューションエクスプローラーの画面写真も添付します。 ヘッダーファイルもインクルードしていますし、ソリューションの中に入れたつもりですが、なぜ Time が定義されていないといわれるのでしょうか? どうぞよろしくお願いいたします。

  • C++での入出力演算子のオーバーロード

    C++学習者です。Visual Studio 2015 を使っています。 入力演算子>> と出力演算子<<をオーバーロードする関数をfriend としてクラス定義の中に書きましたが、”メンバーではありません” というメッセージが出てきてコンパイルできません。 エラー番号はC2039です。 何回調べても原因がわからないので、詳しい方にお聞きしたいです。 どうかよろしくお願いいたします。 ヘッダーファイルと関数定義ファイル、クライアントプログラムと、エラーメッセージのコピーを張り付けてあります。 // クラスヘッダーファイル // class Array header #ifndef ARRAY1_H #define ARRAY1_H #include <iostream> using namespace std; class Array { // operator overloading as non-member functions friend ostream &operator<<(ostream &, const Array &); friend istream &operator>>(istream &, Array &); public: Array(int = 10); // constructor with default of 10 elements of array Array(const Array &); //copy constructor ~Array(); // destructor int getSize() const; // size of array // operator overloadings as member functions const Array &operator=(const Array &); // assignment bool operator==(const Array &) const; // check equality of two arrays // because both sides of the operator are constant, // this function must be constant too bool operator!=(const Array &right) const { // fully defined function in the header file like this one // will be made in-line function and save overhead time return !(*this == right); } int &operator[](int); // check subscript range for non-constant array const int &operator[](int) const; // check subscript range for constant array // remember we can only invoke constant function of a constant object // so if we want to check the subscript range of a constant object, we need // to use a constant member function of that object, that's why we need a // constant version of the same functionn as above operator[] private: int size; // size of array int *ptr; // pointer to the first element of the array // so ptr is the name of the array }; // end of class Array definition #endif // 関数定義ファイル // array1.cpp // member function definitions of class Array #include "stdafx.h" #include <iostream> #include <iomanip> using namespace std; using std::cout; #include <new> // for new and delete #include <cstdlib> // for exit() using std::exit; #include "array1.h" // >> , << 以外のオーバーロード関数は省略します // input operator overloading istream &Array::operator>>(istream &input, Array &a) { for (int i = 0; i < a.size; i++) input >> a.ptr[i]; return input; } // output operator overloading ostream &Array::operator<<(ostream &output, const Array &a) { int i; for (i = 0; i < a.size; i++) { output << setw(12) << a.ptr[i]; if ((i + 1) % 4 == 0) output << endl; } if (i % 4 != 0) output << endl; return output; } // クライアントプログラム // ConsoleApplication87.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include <iostream> using namespace std; #include "array1.h" int main() { Array integers1(7); // 7 elements array Array integers2; // default 10 element array cout << "size of array integer1 is " << integers1.getSize() << endl; cout << "contents of integers1 after instantiation are :\n"; cout << integers1; cout << "---------------------------------------------\n"; cout << "size of array integers2 is " << integers2.getSize() << endl; cout << "contents of integers2 after instantiation are :\n"; cout << integers2; cout << "---------------------------------------------\n"; return 0; } // エラーメッセージ 1>------ ビルド開始: プロジェクト:ConsoleApplication87, 構成:Debug Win32 ------ 1> array1.cpp 1>c:\users\shiro\documents\visual studio 2015\projects\consoleapplication87\consoleapplication87\array1.cpp(96): error C2039: '>>': 'Array' のメンバーではありません。 1> c:\users\shiro\documents\visual studio 2015\projects\consoleapplication87\consoleapplication87\array1.h(9): note: 'Array' の宣言を確認してください 1>c:\users\shiro\documents\visual studio 2015\projects\consoleapplication87\consoleapplication87\array1.cpp(104): error C2039: '<<': 'Array' のメンバーではありません。 1> c:\users\shiro\documents\visual studio 2015\projects\consoleapplication87\consoleapplication87\array1.h(9): note: 'Array' の宣言を確認してください ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

  • C++ proxy class の質問

    C++の学習者です。Visual Studio Community 2015の上で、教本を使って勉強しています。 その中でproxy class のサンプルコードがあり、忠実にキーボードから入力してビルドしようとしたのですが、添付画面写真のようなエラーメッセージが出て、出来ませんでした。 ちゃんとクラスの定義ファイルもありますので、「識別子がクラス名でも名前空間名でもありません。」などというメッセージがどうして出るのかわかりません。 詳しい方がいらっしゃいましたら、どうぞ教えて頂きたく、お願いいたします。 プロジェクトに含まれるソースファイルやヘッダーファイルなどを下にコピーしてあります。 (1) メインプロジェクトファイル : // ConsoleApplication84.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // example of proxy class #include "stdafx.h" #include <iostream> #include <iomanip> #include <cstdlib> #include <ctime> #include <cmath> #include <cstring> #include <new> using namespace std; #include "interface.h" int main() { Interface i(5); cout << "interface contains : " << i.getValue() << " before setValue()" << endl; i.setValue(10); cout << "interface contains : " << i.getValue() << " after setValue()" << endl; return 0; } (2) Implementation クラスのヘッダー... クライアントから隠しておきたいクラス #pragma once // header file for class Implementation // example of proxy class class Implementation { public: // constructor Implementation(int v) : value(v) // initialization syntax { // empty body } // set value to v void setValue(int v) { value = v; } // return value int getValue() const { return value; } private: int value; };// end class definition (3) Interface クラスのヘッダー ... Implementation の proxy class #pragma once // header file for Interface class class Implementation; // forward class declaration // use this format when a pointer or reference to // class Implementation is used // do not write as " #include "inplementation.h" " class Interface { // this is the proxy class of Implementation class public: Interface(int); void setValue(int); int getValue() const; ~Interface(); private: Implementation *ptr; // use a pointer to an object in Implementation class }; 【4】Interface クラスの関数定義 // interface.cpp // definition of member function for Interface class #include "interface.h" #include "implementation.h" #include "stdafx.h" // constructor Interface::Interface(int v) : ptr (new Implementation(v)) // initialize pointer { // empty body } // set value function void Interface::setValue(int v) { ptr->setValue(v); // do not take the form of assigning the value to the private pointer ptr // but use the public function of setValue() of Implementation class through pointer ptr // this way the client(or main() program ) of class Implementation does not access to // the actual inside code of the class definition } // return value int Interface::getValue() const { return ptr->getValue(); } // destructor Interface::~Interface() { delete ptr; }

  • vectorを使用したときのクラス定義について

    現在C++で、STLのvectorを学習しているのですが、 本を見ると ベクトルに保存されるクラスオブジェクトについて 「"<" および "=="を定義する必要がある」 っと書いてあります。 実際のサンプルなどでは、(長くなってしまってすみません) // ベクトルにクラスオブジェクトを保存する #include <iostream> #include <vector> using namespace std; class Demo { double d; public: Demo() { d = 0.0; } Demo(double x) { d = x; } Demo &operator=(double x) { d = x; return *this; } double getd() { return d; } }; bool operator<(Demo a, Demo b) { return a.getd() < b.getd(); } bool operator==(Demo a, Demo b) { return a.getd() == b.getd(); } int main() { vector<Demo> v; int i; for(i=0; i<10; i++) v.push_back(Demo(i/3.0)); for(i=0; i<v.size(); i++) cout << v[i].getd() << ' '; cout << endl; for(i=0; i<v.size(); i++) v[i] = v[i] .getd() * 2.1; for(i=0; i<v.size(); i++) cout << v[i].getd() << ' '; cout << endl; return 0; } っというように書かれています。 ここで、なぜ<や==演算子をオーバーロードする必要があるのかが わかりません。 VC6.0やbccコンパイラで、演算子のオーバーロード箇所をコメントにしても通ってしまいます。 また、本には、「コンパイラによってはその他の比較演算子の定義も必須とされています」っとあります。 お手数おかけしますが、この辺りのことを簡単に(初心者なので・・・)教えていただけたら。と思います。 よろしくお願いします。

  • グローバル変数の定義について質問です。

    下記は私が作成した簡易サンプルプログラムです。 #include <stdio.h> #include <stdlib.h> #include <math.h> double a=1; double b=2; double c=3; double f(){ double y; scanf("%lf",&y) ; return y; } double g(){ double y; y=f()*a; return y; } void main(){ double y; y=g()*b*c; printf("y = \n",y) ; } このプログラムでは実行しても答えが出ません。 グローバル変数でscanfを使用して入力した値を上記double g()で使用することは不可能なのでしょうか。 また、もし可能な方法があるのでしたら教えていただければ幸いです。 よろしくお願いします。

  • c++での入出力がうまくいきません;

    初心者ですが独習c++でプログラミングについて勉強している者です。 なんとか環境設定もできたと思いきや、うまくコンパイルすることができなくて困っています。具体的には、 #include <iostream> using namespace std; int main() { int i, j; double d; i = 10; j = 20; d = 99.101; cout << "値を表示: "; cout << i << ' ' << j << ' ' << d; return 0; } という値を表示するプログラムではコンパイルもうまくいったのですが、次の #include <iostream> using namespace std; int main() { int i; cout << "値を入力: "; cout >> i; cout << "入力した値: " << i << "\n"; return 0; } という入力のプログラムをコンパイルしようとすると、コマンドプロンプトに演算子が使われたクラス ostream では int型の定義が存在しないとなりコンパイルエラーとなってしまいます。 理由が考えてもわからないので、質問してみました。 どのようにすれば、このエラーを解消できるのか知りたいので、どうかご意見をよろしくお願いします。

  • C++ の while ループ

    C++の基本学習者です。Windows 10 で Visual Studio Community 2015 を使っています。 教本に載っている、機械語のプログラムをC++でシミュレーションする、というものを作ろうと、途中まで下のようなコードを書き込み、そこまで間違いがないかを確かめるために、コンパイルして実行したら、添付の写真のようなエラーメッセージが出てきました。 // ConsoleApplication65.cpp : メイン プロジェクト ファイルです。 #include "stdafx.h" #include <iostream> #include <iomanip> #include <cstdlib> #include <ctime> #include <cmath> #include <cstring> using namespace System; using namespace std; int main() { // variables int program = 0; int accumulator = 0; int count = 0; int instructionRegister = 0; int operationCode = 0; int operand = 0; int location[100]; cout << "*** Welcome to Simpletron ***" << endl; cout << "*** Please enter your program ***" << endl; cout << "*** one instruction at a time,***" << endl; cout << "*** after the location number and and the prompt of '?' ***" << endl; cout << "*** To stop entering instructions, ***" << endl; cout << "*** enter -9999 . ***" << endl << endl; cout << setfill('0') << internal; cout << setw(3) << count << " ? "; cin >> program; while (program != -9999) { location[count] = program; count++; } return 0; } while ループに問題がありそうですが、コンパイルはちゃんとできたのに、何が悪いのでしょうか? 詳しい方、どうぞ教えてください。お願いします。

  • 【C++】関数からクラスに変更するには?

    いつも大変お世話になっています。 VC++初心者です。 関数をクラス化していきたいのですが、具体的にどのようにしたら良いか ご指導頂けませんでしょうか。 例えば、このようなソースがあった場合、どのようにクラス化させるのでしょうか。 (また、下記の例ですと、pulsとsubで1つのグループ、 goodMoringとgoodNightで1つのグループにさせる場合には どうすれば宜しいでしょうか。) //======================= //Tool.hの中身 //======================= int plus(int x, int y); int sub(int x, int y); void goodMorning(); void goodNight(); //======================= //Tool.cppの中身 //======================= #include <iostream.h> int plus(int x, int y){ return x + y; } int sub(int x, int y){ return x - y; } void goodMorning(){ cout << "おはよう\n"; } void goodNight(){ cout << "こんばんは\n"; } //======================= //Main.cppの中身 //======================= #include <iostream.h> #include "Tool.h" int main(){ int a = puls(1,1); cout << a <<'\n'; int b = puls(2,1); cout << b <<'\n'; goodMorning(); goodNight(); }

  • C++言語の非常に初歩的な質問(数表)

    今、C++言語を勉強中です。 そこで数表を作るみたいな例題があるのですがどうしても思ったとおりになってくれません。 いろんなことを考えましたが自分の力ではどうにもなりません・・・・。 そこで間違いがあれば指摘していただけたらと思い質問させていただきます。 以下がそのプログラム?です。よろしくお願いします。 #include<iostream.h> #include<math.h> #include<iomanip.h> main() { int n ; double n3 , n5; cout << setw(5) << "n" << setw(10) << "1/n" << setw(10) << "n^1/3" << "\n"; cout << setiosflags(ios::fixed); for(n=1 ; n<=25 ; ++n) { n3=1/n ; n5=pow(n,1/3) ; cout << setw(5) << n << setw(10) << setprecision(5) << n3 << setw(10) << setprecision(5) << n5 << "\n" ; } return 0 ; }

専門家に質問してみよう