我有两个矩阵类,一个用于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并以 Release模式进行编译。
任何人都有暗示为什么会出现这种明显的非逻辑行为?
谢谢。
最佳答案
它们之所以起作用的关键是因为您同时具有复制构造函数和显式复制赋值运算符。这两件事共同构成了看似未定义的case函数。因此,当您执行此操作时:
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中受益。