指向static_cast有效以避免复制?

时间:2014-12-04 12:05:02

标签: c++ c++11 static-cast

更新

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

3 个答案:

答案 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::fooderived提供了覆盖,b.foo()会调用base::foo。这称为切片。如果你想通过作业保留derived - ness,你必须保留一个引用或指针:

base& b = d;
base* b = &d;

答案 2 :(得分:0)

执行static_cast like *static_cast<foo*>(&b);

是否有缺点

是。这是不必要的噪音。就这样做:

f = b;

它具有完全相同的效果。