分配给在c ++中创建的对象

时间:2013-02-11 14:37:48

标签: c++ templates operator-overloading

我正在编写一些函数来操作矢量数据。

我将对象定义为不可复制的(私有拷贝构造函数和赋值运算符)。

然后我定义了模板化运算符=

template <typename G>
inline const TMatrix &operator=(const G &gen) {
    ir_mat::Copy<G, Dimension>::start(m_data, gen);
    return *this;
}

和一些额外的运算符,例如'+','*',如article中所述。

现在我可以将表达式的结果分配给对象:

Vector3f v1, v2, v3;
v1 = v2 + v3;

为什么我不能声明一个变量并将其分配到一个语句中?

Vector3f v1, v2;
Vector3f v3 = v1 + v2;

是否因为此赋值在实例化变量之前尝试创建临时对象,然后将其复制到新对象中? 我可以使用我的运算符'='来实例化新对象,而无需临时存储吗?我是否必须为此定义一个特殊的构造函数?

更新

我还定义了模板化的复制构造函数(可能是最简单的形式):

template <typename G>
TMatrix(const G &data) {
    operator=(data);
}

现在我也可以将v3实例化为:

Vector3f v3(v1 + v2);

但是其他任务仍然没有运气:

Vector3f v3 = v1 + v2;

2 个答案:

答案 0 :(得分:3)

使用=初始化语法初始化类类型的对象不使用operator=,它使用复制构造函数。也就是说,Vector3f v3 = v1 + v2;Vector3f v3(v1 + v2);相同。如果无法访问您的复制构造函数,您将无法执行此操作。

operator=只会在已构建的对象上调用(与v1 = v2 + v3一样),并且T& operator=(const T&)形式称为副本分配

答案 1 :(得分:3)

这个初始化:

 Vector v3(v1 + v2);

会调用你漂亮的模板化构造函数。

这个初始化:

 Vector v3 = v1 + v2;

最终被翻译成这个:

 Vector v3(Vector(v1 + v2));

本质上,编译器尝试使用复制构造函数,并试图找出如何将初始化程序转换为适当的类型。

选择创建可从随机类型分配的类型,但不能复制分配或复制构造是一个非常奇怪的选择。我看到我假设你这样做是为了避免临时工作是正确的。除非你没有这样做,因为临时工具确实很昂贵,但是因为你想要建立一个将在以后评估的表达式。大概是因为你想要对复杂的表达式评估进行矢量化。

是的,您将无法使用初始化的分配形式。至少,我想不出让它发挥作用的方法。

我的建议是以某种方式将Vector转换为您正在构建的表达式的句柄。该句柄可以是一个输入的实数向量的句柄。或者它可能是VectorExpression的句柄,它是对向量进行操作的结果。

如果您不希望共享所有对象的所有权,则仍然无法实现复制分配或复制构造。但是在C ++ 11中,你仍然可以实现移动构造并移动句柄的赋值。