class foo {
public:
foo() : x_(0) { std::cout << "foo constructor\n"; }
foo(foo& c) : x_(c.x_) { std::cout << "foo copy- constructor\n"; }
foo& operator=(foo const& c) {
std::cout << "foo operator=\n";
x_ = c.x_;
return *this;
}
protected:
int x_;
};
class bar : public foo {
public:
bar(int x) { foo::x_ = x; std::cout << "bar constructor\n"; }
bar(bar& c) { std::cout << "bar copy- constructor\n"; }
bar& operator=(bar const& c) {
foo::operator=(c);
std::cout << "bar operator=\n";
return *this;
}
};
int main() {
foo f;
bar b(123);
std::cout << "f = *static_cast<foo*>(&b);\n";
f = *static_cast<foo*>(&b); // no copy constructor is called
std::cout << "f = static_cast<foo>(b);\n";
f = static_cast<foo>(b); // copy constructor and assignment is called
}
输出:
g++ -std=c++11 -Wall -pedantic -o main main.cpp && ./main
foo constructor
foo constructor
bar constructor
f = *static_cast<foo*>(&b);
foo operator=
f = static_cast<foo>(b);
foo copy- constructor
foo operator=
有没有做像*static_cast<foo*>(&b);
这样的static_cast,而 调用复制构造函数就像你在输出中看到的一样。见工作示例here。
答案 0 :(得分:2)
在现在完全不同的问题中:
f = *static_cast<foo*>(&b);
相当于
f = b;
调用foo& operator=(foo const& c)
而没有额外的临时工具。然而,
f = static_cast<foo>(b);
相当于:
f = foo(b);
或
{
foo temporary(b); // calls foo(foo const& );
f = temporary; // calls foo& operator=(foo const& );
}
创建一个临时的。绝对喜欢做:
f = b;
答案 1 :(得分:0)
鉴于现在正在运行的代码,这一行:
base b = *static_cast<base*>(&d);
完全等同于这两个:
base b = static_cast<b&>(d);
base b = d;
在每种情况下,我们都会调用base(base const&)
而没有临时副本。 d
仅被视为const base&
。
执行此构造存在缺点(static_cast
仅在添加噪声之外),即b
只是一个base
对象。它不是derived
类型。因此,如果您有一些虚拟函数base::foo
,derived
提供了覆盖,b.foo()
会调用base::foo
。这称为切片。如果你想通过作业保留derived
- ness,你必须保留一个引用或指针:
base& b = d;
base* b = &d;
答案 2 :(得分:0)
执行
是否有缺点static_cast like *static_cast<foo*>(&b);
是。这是不必要的噪音。就这样做:
f = b;
它具有完全相同的效果。