z****e 发帖数: 2024 | 1 class Base {
public:
virtual Base* clone() =0;
};
class Derived : public Base {
public:
virtual Derived* clone(){
return new Derived(*this);
}
};
int main() {
Base* b = new Derived;
Derived* d2 = b->clone();
return 0;
}
error: invalid conversion from ‘Base*’ to ‘Derived*’ |
z****e 发帖数: 2024 | |
X****r 发帖数: 3557 | 3 b->clone()返回Base*,你要赋给Derived*,自然报错,
用dynamic_cast
【在 z****e 的大作中提到】 : class Base { : public: : virtual Base* clone() =0; : }; : class Derived : public Base { : public: : virtual Derived* clone(){ : return new Derived(*this); : } : };
|
z****e 发帖数: 2024 | 4 可是调用的是derive的版本啊。
【在 X****r 的大作中提到】 : b->clone()返回Base*,你要赋给Derived*,自然报错, : 用dynamic_cast
|
X****r 发帖数: 3557 | 5 b的静态类型是Base*,b->clone()所返回的静态类型就是Base*,
虽然在你这里它的动态类型是Derived*。
所以不能直接赋值给Derived*变量而要用dynamic_cast。
【在 z****e 的大作中提到】 : 可是调用的是derive的版本啊。
|
z****e 发帖数: 2024 | 6 我还不是太懂你的意思。
我也知道b的静态类型是Base*,但是这个和虚函数返回类型有什么联系呢?
难道,虚函数返回值的类型,不是决定于虚函数本身的签名么?
而是决定于调用该虚函数的指针的类型吗?
既然已经找到了derived的虚指针,查虚表,发现要返回一个derived*,就返回,这难道
有问题?
vptr并没有因为b的静态类型是Base*,而改变vptr本身的行为啊?
【在 X****r 的大作中提到】 : b的静态类型是Base*,b->clone()所返回的静态类型就是Base*, : 虽然在你这里它的动态类型是Derived*。 : 所以不能直接赋值给Derived*变量而要用dynamic_cast。
|
t****t 发帖数: 6806 | 7 in c++, type is static bind, unless dynamic_cast is involved.
【在 z****e 的大作中提到】 : 我还不是太懂你的意思。 : 我也知道b的静态类型是Base*,但是这个和虚函数返回类型有什么联系呢? : 难道,虚函数返回值的类型,不是决定于虚函数本身的签名么? : 而是决定于调用该虚函数的指针的类型吗? : 既然已经找到了derived的虚指针,查虚表,发现要返回一个derived*,就返回,这难道 : 有问题? : vptr并没有因为b的静态类型是Base*,而改变vptr本身的行为啊?
|
e**u 发帖数: 409 | 8 是不是因为this是Base*?
【在 t****t 的大作中提到】 : in c++, type is static bind, unless dynamic_cast is involved.
|
X****r 发帖数: 3557 | 9 你说什么呢。现在是编译错误,和什么vptr都没关系。Base::clone()
声明的返回类型是Base*,所以b->clone()这个表达式的类型就是Base*。
【在 z****e 的大作中提到】 : 我还不是太懂你的意思。 : 我也知道b的静态类型是Base*,但是这个和虚函数返回类型有什么联系呢? : 难道,虚函数返回值的类型,不是决定于虚函数本身的签名么? : 而是决定于调用该虚函数的指针的类型吗? : 既然已经找到了derived的虚指针,查虚表,发现要返回一个derived*,就返回,这难道 : 有问题? : vptr并没有因为b的静态类型是Base*,而改变vptr本身的行为啊?
|
z****e 发帖数: 2024 | 10 我靠。是啊。是编译呀。
【在 X****r 的大作中提到】 : 你说什么呢。现在是编译错误,和什么vptr都没关系。Base::clone() : 声明的返回类型是Base*,所以b->clone()这个表达式的类型就是Base*。
|
|
|
z****e 发帖数: 2024 | 11 master shifu也来了?
呵呵。
【在 t****t 的大作中提到】 : in c++, type is static bind, unless dynamic_cast is involved.
|
z****e 发帖数: 2024 | 12 红猪侠一语惊醒梦中人啊。
我又醍醐灌顶了。
【在 X****r 的大作中提到】 : 你说什么呢。现在是编译错误,和什么vptr都没关系。Base::clone() : 声明的返回类型是Base*,所以b->clone()这个表达式的类型就是Base*。
|
z****e 发帖数: 2024 | 13 我越来越觉得自己无比的愚蠢了。
【在 X****r 的大作中提到】 : 你说什么呢。现在是编译错误,和什么vptr都没关系。Base::clone() : 声明的返回类型是Base*,所以b->clone()这个表达式的类型就是Base*。
|
h*****0 发帖数: 4889 | 14 实际调用版本是运行时确定的。编译时只能保证是Base版的。
这个叫late binding
【在 z****e 的大作中提到】 : 可是调用的是derive的版本啊。
|
z****e 发帖数: 2024 | 15 Base版的是叫early binding,也叫静态束定。
我靠,这些道理自以为都明白了,看了个covariant,以为什么牛鼻东东,又被忽悠了。
【在 h*****0 的大作中提到】 : 实际调用版本是运行时确定的。编译时只能保证是Base版的。 : 这个叫late binding
|
t****t 发帖数: 6806 | 16 hmm think again, this is not precise...even if dynamic_cast is involved, the
type is still static bind...you have to decide what type you want dynamic_
cast to cast to before hand...
【在 t****t 的大作中提到】 : in c++, type is static bind, unless dynamic_cast is involved.
|
z***9 发帖数: 696 | 17 virtual Base* clone() =0;
is different from
virtual Derived* clone();
so basically class Derived has two virtual functions? |
z****e 发帖数: 2024 | 18 但是具体能不能cast成功,就是动态的事了。
the
【在 t****t 的大作中提到】 : hmm think again, this is not precise...even if dynamic_cast is involved, the : type is still static bind...you have to decide what type you want dynamic_ : cast to cast to before hand...
|
N***m 发帖数: 4460 | 19 this is sth I do not understand,
but c++ does not allow functions only differnt in return types.
so the compiler should treat them as same virtual funcitons?
【在 z***9 的大作中提到】 : virtual Base* clone() =0; : is different from : virtual Derived* clone(); : so basically class Derived has two virtual functions?
|
d****p 发帖数: 685 | 20 The second one overrides the first one in Derived. So in Derived's vtable
there is only one entry for clone()
whose offset is same as the clone() in Base's vtable.
Before C++98 overriding virtual member functions required both function
signature and return type match.
Now it is same as non virtual function overriding.
【在 z***9 的大作中提到】 : virtual Base* clone() =0; : is different from : virtual Derived* clone(); : so basically class Derived has two virtual functions?
|
|
|
d****p 发帖数: 685 | 21 Yes. There is always a type check before applying any form of cast (implicit
, c style, static, dynamic,
reinterpret).
In your case it is a downcast (Base* -> Derived*) so it could not be
implicit.
【在 z****e 的大作中提到】 : 但是具体能不能cast成功,就是动态的事了。 : : the
|
z****e 发帖数: 2024 | 22 "Now it is same as non virtual function overriding."
你这个又不太严格了啊。
convariant只有pointer和reference作返回值。
【在 d****p 的大作中提到】 : The second one overrides the first one in Derived. So in Derived's vtable : there is only one entry for clone() : whose offset is same as the clone() in Base's vtable. : Before C++98 overriding virtual member functions required both function : signature and return type match. : Now it is same as non virtual function overriding.
|
h*****0 发帖数: 4889 | 23 谁跟你说是early binding的?虚函数啊,当然是late binding的。
了。
【在 z****e 的大作中提到】 : Base版的是叫early binding,也叫静态束定。 : 我靠,这些道理自以为都明白了,看了个covariant,以为什么牛鼻东东,又被忽悠了。
|
d****p 发帖数: 685 | 24 What I meant is it is same as a non virtual function overriding regarding
that their return types don't have to match.
However, your comment drove me to check standard and here below are the
rules (10.3.5):
5 The return type of an overriding function shall be either identical to the
return type of the overridden function or
covariant with the classes of the functions. If a function D::f overrides a
function B::f, the return types of the
functions are covariant if they satisfy the following crite
【在 z****e 的大作中提到】 : "Now it is same as non virtual function overriding." : 你这个又不太严格了啊。 : convariant只有pointer和reference作返回值。
|
t****t 发帖数: 6806 | 25 only virtual functions *override*. non virtual functions only hide, they do
not override.
the
a
【在 d****p 的大作中提到】 : What I meant is it is same as a non virtual function overriding regarding : that their return types don't have to match. : However, your comment drove me to check standard and here below are the : rules (10.3.5): : 5 The return type of an overriding function shall be either identical to the : return type of the overridden function or : covariant with the classes of the functions. If a function D::f overrides a : function B::f, the return types of the : functions are covariant if they satisfy the following crite
|
z****e 发帖数: 2024 | |
d****p 发帖数: 685 | 27 Hmmm initially I thought it was just a matter of wording. After a bit
googling I realized differentiating hide from override is conceptually more
correct - it better illustrates the distinction between compile-time or run-
time function lookup.
So thanks for clearing an issue cheating me for so long time :-)
And hail to C++ since you keep knowing how poor your knowledge about it is
even if you code in it everyday - a sign you always are on learning curve :-
P
do
【在 t****t 的大作中提到】 : only virtual functions *override*. non virtual functions only hide, they do : not override. : : the : a
|
z****e 发帖数: 2024 | 28 是的,是要区分的。其实小声说一句,master shifu 曾经把 name hide和
overload混淆过。还是我给他提的醒。他自己也许不记得了。
嘻嘻嘻嘻。
more
run-
【在 d****p 的大作中提到】 : Hmmm initially I thought it was just a matter of wording. After a bit : googling I realized differentiating hide from override is conceptually more : correct - it better illustrates the distinction between compile-time or run- : time function lookup. : So thanks for clearing an issue cheating me for so long time :-) : And hail to C++ since you keep knowing how poor your knowledge about it is : even if you code in it everyday - a sign you always are on learning curve :- : P : : do
|
a****n 发帖数: 1887 | 29 不同的编译器支持不一样, VC就不支持基于返回值重载
你把derived 的clone 返回值改成 base* 就行了 |
h*****0 发帖数: 4889 | 30 这个不支持说不过去吧……
你说的不会是VC6吧?
【在 a****n 的大作中提到】 : 不同的编译器支持不一样, VC就不支持基于返回值重载 : 你把derived 的clone 返回值改成 base* 就行了
|
|
|
r****t 发帖数: 10904 | 31 covariant return 用在自己身上好像不行啊。
【在 z****e 的大作中提到】 : 这不covariant吗?
|