我在思考如何在C++中構造程序時遇到了一些麻煩。我正在學習一本C++的書,並且一度構建兩個類來解決問題。這本書最終將兩個類,以及它們如何在一個文件中全部使用並運行它,這是有效的。但我知道更合適的結構化代碼將包括頭文件,每個類將獲得它自己的文件,並試圖像這樣構造程序會導致問題,當我試圖獲得代碼編譯。C++程序結構
我有兩個類,Token和Token_Stream,我知道Token和Token_Stream應該有自己的文件,並且每個都應該有一個聲明文件。我的主要問題是:
Token_Stream需要了解令牌。當Token_Stream被初始化時,它初始化一個Token。我曾認爲只需在Token_Stream中包含Token的聲明就足夠了,但似乎並非如此。我知道一些關於用OOP語言進行編程的知識,但Token_Stream不會從Token繼承任何東西,也不應該(它相信)它只需要足夠的知識來初始化Token並存儲它。我將包括各相關文件如下:
Token.h
// Token.h, declaration for Token
class Token
{
public:
char kind;
double value;
Token(char ch);
Token(char ch, double val);
}; //class Token
Token.cpp
// Token.cpp
#include "Token.h"
using namespace std;
Token::Token(char ch)
:kind(ch), value(0){}
Token::Token(char ch, double val)
:kind(ch), value(val) {}
Token_Stream.h
// Token_Stream.h, declarations
class Token_Stream
{
public:
Token_Stream();
Token get();
void putback(Token);
private:
bool full; // do we already hold a token?
Token buffer; // what Token do we hold?
};//class Token_Stream
Token_Stream.cpp
// Token_Stream.cpp implementation.
#include <iostream>
#include <stdexcept>
#include "Token.h" // needs to know what a Token is
#include "Token_Stream.h"
using namespace std;
/***********************************************************************
* Token_Stream::Token_Stream()
*
* Constructor for Token_Stream(), sets full = false and buffer as 0
* Need to do :buffer(0), so we don't create an extra buffer variable
**********************************************************************/
Token_Stream::Token_Stream()
:buffer(0)
{
full = false; // nothing in our stream yet.
}//constructor
/***********************************************************************
* void Token_Stream::put_back(Token t)
*
* Given a token, we fill buffer and change full to true
*
* Parameter: t - Token to fill buffer
**********************************************************************/
void Token_Stream::putback(Token t)
{
if(!full) // if its empty
{
buffer = t;
full = true;
}//if not full
else
throw runtime_error("buffer already full");
}// putback
/***********************************************************************
* Token Token_Stream::get()
*
* gets another token from input, or if we have one stored, gets that.
*
* Returns: Token - next token in stream, either from buffer or from
* input
**********************************************************************/
Token Token_Stream::get()
{
if(full) //if we already have something
{
full = false;
return buffer;
}
//if we've reached here we haven't returned:
char ch;
cin>>ch; //get next input and switch over cases:
switch(ch)
{
// if they input a valid character:
case ';':
case 'q':
case '(': case '+': case '*': case '-': case '/': case '%':
case ')':
return Token(ch);
break;
//if they input a valid number, or lead with a decimal i.e., .5
case '.': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
cin.putback(ch);
double val;
cin>>val; //read it as a number
return Token('8',val);
break;
}//case of valid number
default:
throw runtime_error("Bad Token");
}//switch
}//get
所以這些是文件,當我嘗試編譯東西,即在Token.cpp中放置一個空的int main(){}時,一切工作正常,我編譯,如果我想我可以運行的東西main()的
但是當我試圖把一個空白INT的main(){}在Token_Stream.cpp並嘗試編譯它不工作,我運行:
g++ -Wall -std=c++11 -o "Token_Stream" "Token_Stream.cpp"
,我也不讓行號錯誤,但它聲稱對Token :: Token(char)等的未定義引用以及令牌構造函數的其餘部分,所以我猜這意味着Token_Stream.cpp需要看到更多的Token.cpp,怎麼做我這樣做?我是否同時編譯它們?
您不需要將自己限制爲每個翻譯單元或頭文件一個類。在一個頭文件中有幾個類是很常見的。 – 2014-09-23 19:01:33
緊密相關的類可以保存在同一個文件中。的 – Barmar 2014-09-23 19:02:02
可能重複[未定義引用(http://stackoverflow.com/questions/5293021/undefined-reference-to) – Borgleader 2014-09-23 19:03:00