我有两个矩阵类,一个用于CPU,一个用于GPU,分别说Matrix
和CudaMatrix
。声明和定义位于文件.h
,.cpp
,.cuh
和.cu
中。在main
,我有
Matrix<int2_> foo1(1,2);
// Definition of the elements of foo1...
CudaMatrix<int2_> foo2(1,2);
cout << typeid(foo1).name() << "\n";
cout << typeid(foo2).name() << "\n";
// Equality
foo2=foo1;
现在,operator=
和CudaMatrix
之间没有Matrix
重载,但我有以下operator=
重载
const CudaMatrix& operator=(const CudaMatrix<LibraryNameSpace::int2_>&);
两个CudaMatrix
之间。会发生以下情况:
typeid
会返回foo1
和foo2
的正确类; operator=
重载在运行时编译并调用foo2=foo1
赋值。相反,我原本期望编译错误; foo2
的正确结果!我正在使用Visual Studio 2010并在发布模式下进行编译。
任何人都有一些暗示为什么会发生这种明显不合逻辑的行为?
感谢。
答案 0 :(得分:2)
它们解决这个问题的关键因为你有一个复制构造函数和一个显式复制赋值运算符。将这两件事放在一起,使看似未定义的案例正确起作用。所以当你这样做时:
Matrix<int2_> foo1(1,2);
CudaMatrix<int2_> foo2(1,2);
foo2 = foo1;
会发生什么相当于:
Matrix<int2_> foo1(1,2);
CudaMatrix<int2_> foo2(1,2);
// foo2 = foo1;
{
CudaMatrix<int2_> x(foo1); // copy constructor
foo2 = x; // Copy assignment
}
请注意,这里有一些你应该注意的设备内存使用含义(即两个设备内存分配和两套你在幕后的API调用)。
值得指出的是,这不是CUDA特有的,它是C ++ 98对象模型的标准功能。如果您想了解更多有关其工作原理和原因(以及为什么看似类似的反例不起作用),您可能会受益于修改rule of three。