中国語人民郵便出版の誤り
<>中国語人民郵便出版の誤り訂正
この中国語版にはいろいろな穴のお父さんの小さな間違いがある.例えば変数名の大文字と小文字、同じ変数、大文字と小文字が一致しないなどの問題がある.
そして今日は文法の問題にぶつかったような気がします.権限の継承に関する質問です.
本の中の第8章のdemoの中で、class Exprについてnode.
protectedキーワードが使用されています.でもここExpr_Nodeはベースクラスで、継承に問題が発生します.
具体的なコードは以下の通りです.
ここでprotectedを使えばerror.
protectedは本来、継承が起こらない領域を明確にするためである.ここでこの虚関数の山は継承される.穴を占拠して子類に実現させるためだ.
ここではprotectedではなくpublicを使用するべきです.
「権威に挑戦する」かもしれないので、問題を投げ出して、心ある人が一緒に討論してほしい.
次は完全なコードです.テスト可能
「私の友元の友元は、必ずしも私の友元ではない」と証明するために
すなわち、現在のclass Aは、1つの友元class Bを宣言し、B内部はまた1つの関数FがBの友元であることを宣言する.ではFはclass Aのprivateデータにアクセスできますか?
答えはできません(個人的な観点では、C++primerをひっくり返したので、この問題を繰り返していません.自分でテストしたdemo)
C 1とC 2の2つのクラスを定義しましたC 2がC 1の友元であることは、C 2がC 1のprivateまたはprotectedメンバーにアクセスできることを示す.
でも!これはC 2の友元がC 1のprivate領域にアクセスできるという意味ではない.
次のdemoは私の観点を検証しました.
意図はすべて注釈の中にある.注釈と注釈がないのは
対比
コメントを出すのはc 2_printの中でエラーが発生します.ここC 2はC 1の友元なので、c 2_printはC 2の友元であるが、これは伝達性を持たない.c 2_を代表しないprintはC 1の友元です.
この中国語版にはいろいろな穴のお父さんの小さな間違いがある.例えば変数名の大文字と小文字、同じ変数、大文字と小文字が一致しないなどの問題がある.
そして今日は文法の問題にぶつかったような気がします.権限の継承に関する質問です.
本の中の第8章の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は本来、継承が起こらない領域を明確にするためである.ここでこの虚関数の山は継承される.穴を占拠して子類に実現させるためだ.
ここではprotectedではなくpublicを使用するべきです.
「権威に挑戦する」かもしれないので、問題を投げ出して、心ある人が一緒に討論してほしい.
次は完全なコードです.テスト可能
/*
Programmer : EOF
Date : 2015.05.19
File : 8.4.cpp
E-mail : [email protected]
*/
#include
#include
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<use; };
Expr& operator=(const Expr&);
~Expr() { if(--p->use == 0) delete p;}
int eval() const {return p->eval();}
};
ostream&
operator<use++;
if(--p->use == 0)
{
delete p;
}
p = rhs.p;
return *this;
}
ostream&
operator<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は、1つの友元class Bを宣言し、B内部はまた1つの関数FがBの友元であることを宣言する.ではFはclass Aのprivateデータにアクセスできますか?
答えはできません(個人的な観点では、C++primerをひっくり返したので、この問題を繰り返していません.自分でテストしたdemo)
C 1とC 2の2つのクラスを定義しましたC 2がC 1の友元であることは、C 2がC 1のprivateまたはprotectedメンバーにアクセスできることを示す.
でも!これはC 2の友元がC 1のprivate領域にアクセスできるという意味ではない.
次のdemoは私の観点を検証しました.
#include
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;
}
意図はすべて注釈の中にある.注釈と注釈がないのは
対比
コメントを出すのはc 2_printの中でエラーが発生します.ここC 2はC 1の友元なので、c 2_printはC 2の友元であるが、これは伝達性を持たない.c 2_を代表しないprintはC 1の友元です.