標籤:c++
<<C++ 沉思錄>> 中文人民郵電出版 勘誤
這本中文版裡面有各種坑爹的小錯誤. 比方說變數名的大小寫, 同一個變數, 出現了大小寫不一致, 等等問題都有.
然後今天感覺遇到了個文法問題. 關於繼承許可權的問題.
書中第八章的demo裡面, 關於class Expr_node.
使用了protected關鍵字. 但是這裡Expr_node是基類, 繼承就會出現問題.
具體的代碼如下:
class Expr_node{ friend ostream& operator << (ostream&, const Expr_node&); friend class Expr; int use;// @use is a counter to avoid copying objects. //protected: public: Expr_node(): use(1) { } virtual void print(ostream&) const = 0; virtual ~Expr_node() { } virtual int eval() const = 0;};
這裡用protected就會error.
protected本來就是為了明確不發生繼承的地區. 這裡這堆虛函數是要發生繼承的.就是為了占坑了讓子類去實現.
這裡應該使用public, 而不是 protected.
由於可能在"挑戰權威" , 所以把問題拋出來, 希望有心人能一起討論.
下面是完整的代碼. 可供測試
/* Programmer : EOF Date : 2015.05.19 File : 8.4.cpp E-mail : [email protected] */#include <iostream>#include <string>using namespace std;/* This @Expr_node is the base-class. */class Expr_node{ friend ostream& operator << (ostream&, const Expr_node&); friend class Expr; int use;// @use is a counter to avoid copying objects. protected: //public: Expr_node(): use(1) { } virtual void print(ostream&) const = 0; virtual ~Expr_node() { } virtual int eval() const = 0;};class Expr{ friend ostream& operator<<(ostream&, const Expr&); Expr_node* p; public: Expr():p(NULL){} Expr(int); Expr(const string&, Expr); Expr(const string&, Expr, Expr); Expr(const Expr& t) { p = t.p; ++p->use; }; Expr& operator=(const Expr&); ~Expr() { if(--p->use == 0) delete p;} int eval() const {return p->eval();}};ostream&operator<<(ostream& o, const Expr_node& e){ e.print(o); return o;}Expr&Expr::operator=(const Expr& rhs){ rhs.p->use++; if(--p->use == 0) { delete p; } p = rhs.p; return *this;}ostream&operator<<(ostream& o, const Expr& t){ t.p->print(o); return o;}class Int_node: public Expr_node{ friend class Expr; int n; Int_node(int k): n(k) { } void print(ostream& o) const { o << n;} int eval() const { return n;}};class Unary_node: public Expr_node{ friend class Expr; string op; Expr opnd; Unary_node(const string& a, Expr b): op(a), opnd(b) { } void print(ostream& o) const { o << "(" << op << opnd << ")"; } int eval() const { if(op == "-") { return -opnd.eval(); } throw "error, bad op" + op + "int UnaryNode"; }};class Binary_node: public Expr_node{ friend class Expr; string op; Expr left; Expr right; Binary_node(const string& a, Expr b, Expr c): op(a), left(b), right(c) { } void print(ostream& o) const { o << "(" << left << op << right << ")"; } int eval() const { int op1 = left.eval(); int op2 = right.eval(); if(op == "-") return op1 - op2; if(op == "+") return op1 + op2; if(op == "*") return op1 * op2; if(op == "/") return op1 / op2; if(op == "/" && op2 != 0) return op1/ op2; throw "error, bad op" + op + "int BinaryNode"; }};Expr::Expr(int n){ p = new Int_node(n);}Expr::Expr(const string& op, Expr t){ p = new Unary_node(op, t);}Expr::Expr(const string& op, Expr left, Expr right){ p = new Binary_node(op, left, right);}int main(){ Expr t = Expr("*", Expr("-", 5), Expr("+", 3, 4)); cout << t << " = " << t.eval() << endl; t = Expr("*", t, t); cout << t << " = " << t.eval() << endl; return 0;}
<<C++ 沉思錄>> 中文人民郵電出版 勘誤