p*****u 发帖数: 711 | 1 #include
class A {
public:
void print();
};
void A::print() {
cout << "A.print"<< endl;
}
class B: publicA {
}
int main() {
B obj;
obj.print();
return 0;
}
output is "A.print"
接下来
#include
class A {
public:
virtual void print();
};
void A::print() {
cout << "A.print"<< endl;
}
class B: publicA {
}
void B::print(){ count << "B.print" << endl;}
int main() {
B obj;
obj.print();
return 0;
}
error: no 'void B::print()' member function declared in class 'B'
如果想overide base class 里面的虚函数print,一定先要在derived class 里面
declare, 如果不delcare, B::print 这个表述就是无效的, 这样理解是否正确?
第一个case, 为什么obj.print可以运行, 时候说明symbol table 里面有B.obj这个函
数? 为什么在第二种情况下,需要在重新声明呢? 谢谢各位。 |
N***m 发帖数: 4460 | 2 和virtual没关系。
第一种清况下要是重写B::print,你也得声名
【在 p*****u 的大作中提到】 : #include : class A { : public: : void print(); : }; : void A::print() { : cout << "A.print"<< endl; : } : class B: publicA { : }
|
p*****u 发帖数: 711 | 3 是的,但是觉得不是很intuitive,不知道为什么要声明一下。 |
X****r 发帖数: 3557 | 4 你想要定义一个类的成员函数啊?你要是想要的话你就说话嘛,
你不说我怎么知道你想要呢,虽然你很有诚意地看着我,可是
你还是要跟我说你想要的。你真的想要吗?
如果你要定义B::print,那你就要在B类的定义里声明这个函数。
所有的类的成员函数不都是这样的吗?A::print和B::print是
两个函数,A类的定义里声明有A::print和你要定义一个新的
B::print并不相干。
【在 p*****u 的大作中提到】 : 是的,但是觉得不是很intuitive,不知道为什么要声明一下。
|
l******e 发帖数: 12192 | 5 .....
【在 X****r 的大作中提到】 : 你想要定义一个类的成员函数啊?你要是想要的话你就说话嘛, : 你不说我怎么知道你想要呢,虽然你很有诚意地看着我,可是 : 你还是要跟我说你想要的。你真的想要吗? : 如果你要定义B::print,那你就要在B类的定义里声明这个函数。 : 所有的类的成员函数不都是这样的吗?A::print和B::print是 : 两个函数,A类的定义里声明有A::print和你要定义一个新的 : B::print并不相干。
|
s*w 发帖数: 729 | 6 the interviewer got to be Chinese wsn to appreciate
【在 X****r 的大作中提到】 : 你想要定义一个类的成员函数啊?你要是想要的话你就说话嘛, : 你不说我怎么知道你想要呢,虽然你很有诚意地看着我,可是 : 你还是要跟我说你想要的。你真的想要吗? : 如果你要定义B::print,那你就要在B类的定义里声明这个函数。 : 所有的类的成员函数不都是这样的吗?A::print和B::print是 : 两个函数,A类的定义里声明有A::print和你要定义一个新的 : B::print并不相干。
|
a****o 发帖数: 686 | 7 红猪侠,你这样吓到了人家怎么办?尤其是吓到了小朋友怎么办?就算吓不倒小朋友,
吓到了花花草草也不好嘛。
【在 X****r 的大作中提到】 : 你想要定义一个类的成员函数啊?你要是想要的话你就说话嘛, : 你不说我怎么知道你想要呢,虽然你很有诚意地看着我,可是 : 你还是要跟我说你想要的。你真的想要吗? : 如果你要定义B::print,那你就要在B类的定义里声明这个函数。 : 所有的类的成员函数不都是这样的吗?A::print和B::print是 : 两个函数,A类的定义里声明有A::print和你要定义一个新的 : B::print并不相干。
|
p*****u 发帖数: 711 | |
p*****u 发帖数: 711 | 9 但如果不定义B::print.
B obj;
obj.print就会调用A::print, 是否可以这样理解,调用一个obj.print()时,先在
class
B中找print(),如果没有定义,再在class B的supclass 即class A中找? 函数调用时
这个查
找是如何实现的?
#include
class A{
public:
void print();
};
void A::print() {
cout << "A.print" << endl;
}
class B : public A {
public:
void print();
};
int main() {
B obj;
obj.print();
return 0;
}
给出的error msg是
In function `main':
undefined reference to `B::print()'
说明在B中定义print()之后,A的print就被屏蔽了?compiler在定义B::print()时,做
了什么
事情?
望大侠们解惑。。。
【在 X****r 的大作中提到】 : 你想要定义一个类的成员函数啊?你要是想要的话你就说话嘛, : 你不说我怎么知道你想要呢,虽然你很有诚意地看着我,可是 : 你还是要跟我说你想要的。你真的想要吗? : 如果你要定义B::print,那你就要在B类的定义里声明这个函数。 : 所有的类的成员函数不都是这样的吗?A::print和B::print是 : 两个函数,A类的定义里声明有A::print和你要定义一个新的 : B::print并不相干。
|
a****o 发帖数: 686 | 10 这个叫作 “name hide”。
成员函数都是全局函数,不同是,1,用了class name作为namespace,2.pass 一个
this pointer。
B重新定义以后,B的namespace里边就只有重新声明的函数name了。A的被hide了。
【在 p*****u 的大作中提到】 : 但如果不定义B::print. : B obj; : obj.print就会调用A::print, 是否可以这样理解,调用一个obj.print()时,先在 : class : B中找print(),如果没有定义,再在class B的supclass 即class A中找? 函数调用时 : 这个查 : 找是如何实现的? : #include : class A{ : public:
|
p*****u 发帖数: 711 | |
a****o 发帖数: 686 | 12 另外,virtual是会有不同的。
1. A::print是vritual,B::print如果声明,则需要定义。因为B::print此时会继承
virtual属性,故而,vtable需要一个函数地址。没有定义 B::print,则没有函数地址
给vtable去set up。
2. A::print不是vritual, B::print如果声明,不一定需要定义,只要B::print 不被
调用,编译可以通过,因为无需给改函数分配地址。
【在 p*****u 的大作中提到】 : #include : class A { : public: : void print(); : }; : void A::print() { : cout << "A.print"<< endl; : } : class B: publicA { : }
|
a****o 发帖数: 686 | 13 和virtual很有关系。
如果要生成对象实例,则必须给出虚函数定义。
这也是为什么只有abstract class,才能允许没有定义的虚函数存在,因为abstract class,不能实例化。
这也是虚函数和普通成员函数的区别:类实例化的时候,需要地址去set up vtable。
【在 N***m 的大作中提到】 : 和virtual没关系。 : 第一种清况下要是重写B::print,你也得声名
|
p*****u 发帖数: 711 | 14 very good point, thanks very much, Appllo.
class,不能实例化。
【在 a****o 的大作中提到】 : 和virtual很有关系。 : 如果要生成对象实例,则必须给出虚函数定义。 : 这也是为什么只有abstract class,才能允许没有定义的虚函数存在,因为abstract class,不能实例化。 : 这也是虚函数和普通成员函数的区别:类实例化的时候,需要地址去set up vtable。
|