C ++ - 创建时调用赋值运算符而不是复制构造函数

时间:2010-09-17 16:45:32

标签: c++ copy-constructor assignment-operator

我想在类似本机类型的结构体之间强制执行显式转换:

int i1;
i1 = some_float; // this generates a warning
i1 = int(some_float): // this is OK
int i3 = some_float; // this generates a warning

我想使用赋值运算符和复制构造函数来做同样的事情,但行为是不同的:

Struct s1;
s1 = other_struct; // this calls the assignment operator which generates my warning
s1 = Struct(other_struct) // this calls the copy constructor to generate a new Struct and then passes that new instance to s1's assignment operator
Struct s3 = other_struct; // this calls the COPY CONSTRUCTOR and succeeds with no warning

是否有任何技巧可以使第三种情况Struct s3 = other_struct;使用默认构造函数构造s3,然后调用赋值运算符?

这一切都按照应有的方式编译和运行。 C ++的默认行为是在创建新实例并且立即调用复制构造函数时调用复制构造函数而不是赋值运算符(即MyStruct s = other_struct;变为MyStruct s(other_struct) ;不是MyStruct s; s = other_struct;。我只是想知道是否有任何技巧来解决这个问题。

编辑:“显式”关键字正是我所需要的!

class foo {
    foo(const foo& f) { ... }
    explicit foo(const bar& b) { ... }
    foo& operator =(const foo& f) { ... }
};

foo f;
bar b;
foo f2 = f; // this works
foo f3 = b; // this doesn't, thanks to the explicit keyword!
foo f4 = foo(b); // this works - you're forced to do an "explicit conversion"

4 个答案:

答案 0 :(得分:4)

免责声明:我已经准备好对此采取行动,因为这不回答这个问题。但这可能对OP有用。

我认为将复制构造函数视为默认构造+赋值是一个非常糟糕的主意。这是另一种方式:

struct some_struct
{
    some_struct();  // If you want a default constructor, fine
    some_struct(some_struct const&); // Implement it in the most natural way
    some_struct(foo const&);         // Implement it in the most natural way

    void swap(some_struct&) throw(); // Implement it in the most efficient way

    // Google "copy and swap idiom" for this one
    some_struct& operator=(some_struct x) { x.swap(*this); return *this; }

    // Same idea
    some_struct& operator=(foo const& x)
    {
        some_struct tmp(x);
        tmp.swap(*this);
        return *this;
    }
};

以这种方式实现的东西是万无一失的,并且是你在C ++中转换语义方面所能获得的最好的东西,所以它是 的方式来到这里。

答案 1 :(得分:3)

如果重载other_struct的类型转换运算符,并且相应地编辑原始结构,则可以解决此问题。也就是说,它非常混乱,并且通常没有充分的理由这样做。


#include <iostream>

using namespace std;

struct bar;

struct foo {
    explicit foo() {
        cout << "In foo default constructor." << endl;
    }

    explicit foo(bar const &) {
        cout << "In foo 'bar' contructor." << endl;
    }

    foo(foo const &) {
        cout << "In foo constructor." << endl;
    }

    foo const & operator=(bar const &) {
        cout << "In foo = operator." << endl;
        return *this;
    }
};

struct bar {
    operator foo() {
        cout << "In bar cast overload." << endl;
        foo x;
        x = *this;
        return x;
    }
};

int main() {
    bar b;
    foo f = b;
    return 0;
}

输出:

In bar cast overload.
In foo default constructor.
In foo = operator.
In foo constructor.
In foo constructor.

答案 2 :(得分:2)

简而言之,没有。

长版......实际上是关于它的。这不是它的工作原理。不过要想出一些东西来填补角色的要求。

答案 3 :(得分:0)

我不这么认为。当你写

Struct s3 = other_struct;

它看起来像一个赋值,但实际上它只是调用构造函数的声明性语法。