<<C++ 沉思录>> 中文人民邮电出版 勘误
来源:互联网 发布:淘宝花呗怎么开通不了 编辑:程序博客网 时间:2024/04/29 17:48
<<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 : jasonleaster@gmail.com */#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;}
为了证明"我的友元的友元,不一定是我的友元"
也就是说, 当前class A, 声明了一个友元 class B, 而B内部又声明了一个函数F是B的友元.那么F能访问class A的private数据嘛?
答案是不能(个人观点, 因为我翻了C++ primer, 也没有着重讲这个问题, 自己测试的demo)
我这里就特意定义了两个类, C1和C2. C2是C1的友元, 就说明C2能够访问C1的private 或者protected成员.
但是! 这不意味着C2的友元能够访问C1的private区域.
下面的demo验证了我的观点:
#include <iostream>using namespace std;class C1;class C2;class C1{ public: C1(const char* s): str_c1(s) { } friend void c1_print(class C1&); friend C2; private: const char* str_c1;};class C2{ public: C2(const char* s): str_c2(s){} private:// friend void c2_print(class C1&); const char* str_c2;};void c1_print(class C1 &tmp_c1){ tmp_c1.str_c1 = "hello world";}void c2_print(class C1 &tmp_c1){// tmp_c1.str_c1 = "hello world";}int main(){ class C1 tmp_c1("I'm c1"); class C2 tmp_c2("I'm c2"); //c2_print(tmp_c1); c1_print(tmp_c1); return 0;}
意图都在注释里面. 把注释和没有注释的是对比.
把注释放出来就是在c2_print里面会发生报错. 因为这里C2 是C1的友元, c2_print是C2的友元, 但是这不具有传递性.不代表c2_print就是C1的友元.
0 0
- <<C++ 沉思录>> 中文人民邮电出版 勘误
- 设计模式沉思录——互动出版网
- 沉思录
- 沉思录
- 沉思录
- 《沉思录》
- 沉思录
- 沉思录
- 沉思录
- 本人参与翻译的图书《编程人生:15位软件先驱访谈录》已经由人民邮电出版社出版
- 本人参与翻译的图书《编程人生:15位软件先驱访谈录》已经由人民邮电出版社出版
- 表达式 《c++沉思录》第八章
- [C++]c++沉思录第10章例子“字符图像”
- 《C++沉思录:Ruminations on C++》Picture类
- 【iOS沉思录】Objective-C中的多态性分析
- 【IOS沉思录】Objective-C中的糖衣语法(字面量)
- 【iOS沉思录】深思Objective-C中的property属性
- 沉思录:垫脚石
- IE文档模式
- my work note from new job
- Java中sql语句之通配符*
- MATLAB调用C/C++函数的方法
- 开发中注意点
- <<C++ 沉思录>> 中文人民邮电出版 勘误
- JAVA设计模式:原型模式
- 人才芯片&Jfinal
- linux mint17 安装openssl包
- CDH5.x 使用Spark-sql
- 健康项目管理优秀实践及运用-讲师团俊平老师主讲
- BASE64编码and解码的C实现
- x264源代码简单分析:宏块分析(Analysis)部分-帧内宏块(Intra)
- GET 和 POST