c*******9 发帖数: 6411 | 1 【 以下文字转载自 Quant 讨论区 】
发信人: jsyzghan (民兵营长), 信区: Quant
标 题: 码工试题
发信站: BBS 未名空间站 (Thu Mar 11 10:54:48 2010, 美东)
N年之前的,某著名银行的一老俄问的.现在也没想出来.
Given these classes:
struct A
{
A() { throw 0; }
};
struct B : A
{
B();
};
With absolutely no change to the above, implement B::B() so that it does
not throw. |
X****r 发帖数: 3557 | 2 这个可能吗?要是B::B()既没有完成又不throw,到时候岂不是还要调用~B:B()?
这不是自己挖个坑跳下去嘛。
【在 c*******9 的大作中提到】 : 【 以下文字转载自 Quant 讨论区 】 : 发信人: jsyzghan (民兵营长), 信区: Quant : 标 题: 码工试题 : 发信站: BBS 未名空间站 (Thu Mar 11 10:54:48 2010, 美东) : N年之前的,某著名银行的一老俄问的.现在也没想出来. : Given these classes: : struct A : { : A() { throw 0; } : };
|
X****r 发帖数: 3557 | 3 当然如果是脑筋急转弯的话……
struct BB {
BB() { /* I don't throw! */}
};
#define B BB
【在 X****r 的大作中提到】 : 这个可能吗?要是B::B()既没有完成又不throw,到时候岂不是还要调用~B:B()? : 这不是自己挖个坑跳下去嘛。
|
h*****0 发帖数: 4889 | 4 B::B() : A( *( (A*) (new int) ) ) {}
【在 c*******9 的大作中提到】 : 【 以下文字转载自 Quant 讨论区 】 : 发信人: jsyzghan (民兵营长), 信区: Quant : 标 题: 码工试题 : 发信站: BBS 未名空间站 (Thu Mar 11 10:54:48 2010, 美东) : N年之前的,某著名银行的一老俄问的.现在也没想出来. : Given these classes: : struct A : { : A() { throw 0; } : };
|
X****r 发帖数: 3557 | 5 这个倒是个解法……虽然一样没有实际的用处,不过比我上面那个强得多。
【在 h*****0 的大作中提到】 : B::B() : A( *( (A*) (new int) ) ) {}
|
D****A 发帖数: 360 | 6 clever!
It could be even simpler. I tried this:
B::B()
:A(*(A *)0)
{}
【在 h*****0 的大作中提到】 : B::B() : A( *( (A*) (new int) ) ) {}
|
X****r 发帖数: 3557 | 7 dereferencing a null pointer is technically undefined behavior...
【在 D****A 的大作中提到】 : clever! : It could be even simpler. I tried this: : B::B() : :A(*(A *)0) : {}
|
D****A 发帖数: 360 | 8 yea... dereferencing a null ptr is undefined, but in this code, the *0 is
passed as argument to a copy constructor which does nothing. ;)
Runtime error can be arbitrary. ``new int'' is not safe either.
So, come on, its just a trick.
【在 X****r 的大作中提到】 : dereferencing a null pointer is technically undefined behavior...
|
d****p 发帖数: 685 | 9 In this case (the A is an empty class) the copy constructor of A is
optimized away when initializing B and the
null pointer does no harm.
If you however add an int member variable in A, you will have a segmentation
fault.
So perhaps the following is OK:
B::B() : A(*(static_cast(malloc(sizeof(A)))) {}
【在 D****A 的大作中提到】 : yea... dereferencing a null ptr is undefined, but in this code, the *0 is : passed as argument to a copy constructor which does nothing. ;) : Runtime error can be arbitrary. ``new int'' is not safe either. : So, come on, its just a trick.
|
D****A 发帖数: 360 | 10 你说的对,其实你这个也不完美
不如 B::B() :A(*(A *)this) {}
segmentation
【在 d****p 的大作中提到】 : In this case (the A is an empty class) the copy constructor of A is : optimized away when initializing B and the : null pointer does no harm. : If you however add an int member variable in A, you will have a segmentation : fault. : So perhaps the following is OK: : B::B() : A(*(static_cast(malloc(sizeof(A)))) {}
|
|
|
d****p 发帖数: 685 | 11 If in B's object layout A is placed after B, we don't know what will happen
code will put B's virtual table pointer into A :-(
Basically when we try to initialize A during B's initialization list, point
this is totally not ready and it is a bad
idea to even think about using it. |
h*****0 发帖数: 4889 | 12 我感觉this指针在那个地方,会通不过编译。
happen
point
【在 d****p 的大作中提到】 : If in B's object layout A is placed after B, we don't know what will happen : code will put B's virtual table pointer into A :-( : Basically when we try to initialize A during B's initialization list, point : this is totally not ready and it is a bad : idea to even think about using it.
|
D****A 发帖数: 360 | 13 完全没问题的,要不然C++的子类static cast成父类的实现就有问题了
【在 h*****0 的大作中提到】 : 我感觉this指针在那个地方,会通不过编译。 : : happen : point
|
d****p 发帖数: 685 | 14 hmm.. At that time, this is firmly valid (though not property initialized)
so I guess compiler will allow dereferencing this in the derived class's
ctor's initialization list; it is however programmer's responsibility to
make sure it is used properly.
Consider the following legitimate example:
class Foo
{
....int a;
public:
....Foo(int a) : a(a) {}
....int IncA() { return a; }
};
class Bar : public Foo
{
... int b;
public:
....Bar(int x) : Foo(x), b(this->IncA()) {}
};
In the list after Foo is i
【在 h*****0 的大作中提到】 : 我感觉this指针在那个地方,会通不过编译。 : : happen : point
|
D****A 发帖数: 360 | 15 the use of ``this'' is totally benign here since the compiler knows exactly
where the A part in B is, no matter what implementation it is. Therefore
the copy constructor copies A to itself. Typically &B equls &static_cast(
B)
but that's not even necessary here.
happen
point
【在 d****p 的大作中提到】 : If in B's object layout A is placed after B, we don't know what will happen : code will put B's virtual table pointer into A :-( : Basically when we try to initialize A during B's initialization list, point : this is totally not ready and it is a bad : idea to even think about using it.
|
D****A 发帖数: 360 | 16 class Foo
{
....int a;
public:
....Foo(int a) : a(a) {}
....int IncA() { return a; }
};
class Bar : public Foo
{
... int b;
public:
....Bar(int x) : Foo(x), b(this->IncA()) {}
};
In the list after Foo is initialized, it is ok to invoke IncA via this->IncA
() which will be translated to Foo::IncA since IncA is not virtual.
In case IncA is virtual, I agree with you that a good compiler should forbit
using "this" to call any virtual function since at that time vtable is
perhaps not ready.
In the ca
【在 h*****0 的大作中提到】 : 我感觉this指针在那个地方,会通不过编译。 : : happen : point
|
d****p 发帖数: 685 | 17 You are right :-)
exactly
>(
【在 D****A 的大作中提到】 : the use of ``this'' is totally benign here since the compiler knows exactly : where the A part in B is, no matter what implementation it is. Therefore : the copy constructor copies A to itself. Typically &B equls &static_cast( : B) : but that's not even necessary here. : : happen : point
|
d****p 发帖数: 685 | 18
. If it is pure
virtual you'll have compiler error anyways.
Suppose IncA() is virtual.
Compiler normally constructs Bar's vtable in Bar's constructor body; so in
the initialization list this->IncA()
will look for B's vtable which is unfortunately not ready.
Anyway I guess at that time Foo's vtable may be ready and the form (static_
castthis)->IncA() may work.
【在 D****A 的大作中提到】 : class Foo : { : ....int a; : public: : ....Foo(int a) : a(a) {} : ....int IncA() { return a; } : }; : class Bar : public Foo : { : ... int b;
|
d****p 发帖数: 685 | 19
Correction :-(
this->AnyFunc() seems always a static resolution and has nothing to do with
vtable.
【在 d****p 的大作中提到】 : : . If it is pure : virtual you'll have compiler error anyways. : Suppose IncA() is virtual. : Compiler normally constructs Bar's vtable in Bar's constructor body; so in : the initialization list this->IncA() : will look for B's vtable which is unfortunately not ready. : Anyway I guess at that time Foo's vtable may be ready and the form (static_ : castthis)->IncA() may work.
|