当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 拷贝构造和赋值操作符,C#和本机 C++ 代码的互用性
VC++ 中的 拷贝构造和赋值操作符,C#和本机 C++ 代码的互用性
| C++ At Work 专栏... 下载源代码:CAtWork0509.exe (276KB)
Shadi Hani 乍一看,这似乎是一个答案简单的简单问题:写一个调用 operator= 的构造函数不就行了:CFoo::CFoo(const CFoo& obj) { *this = obj;} 或者,写一个公用的拷贝方法,拷贝构造函数和 operator= 都调用这个方法也行。就像这样: CFoo::CFoo(const CFoo& obj) { CopyObj(obj);}CFoo& CFoo::operator=(const CFoo& rhs) { CopyObj(rhs); return *this;} 对于大多数类来说,这是行得通的,但还有些特殊情况需要考虑。如果你的类包含有数据成员是另一个类的实例会怎样呢?为了弄清楚这个问题,我写了一个测试程序如 Figure 1 所示。它有一个主类 CMainClass,它包含另一个类 CMember 的实例。两个类都有拷贝构造函数和赋值操作,用 CMainClass 的拷贝构造函数调用 operator=,如下面的代码段所示。代码中使用 printf 语句是为了显示何时调用了哪个方法。为了运行构造函数,cctest 程序首先用缺省构造函数创建 CMainClass 实例,然后用拷贝构造函数创建另一个实例: CMainClass obj1;CMainClass obj2(obj1); 如果你编译并运行 cctest,当构造 obj2 时,你会看到下面的 printf 信息: CMember: default ctorCMainClass: copy-ctorCMainClass: operator=CMember: operator= 成员对象 m_obj 被初始化了两次!第一次是缺省构造,第二次是赋值时再次被初始化。嘿,这是怎么回事? CFoo::CFoo() { m_obj = DEFAULT;} 与下面代码相对: CFoo::CFoo() : m_obj(DEFAULT){} 使用赋值方式,m_obj 被初始化两次,而用初始化例程语法,m_obj 只被初始化一次。所以,要如何避免拷贝构造期间额外的初始化呢?当它与你的代码重用初衷相抵触时, 最好的解决俄u方法就是分开实现拷贝构造和赋值操作,即便它们做同样的事情。从拷贝构造中调用 operator= 肯定能行得通,但不是最有效率的实现。我对初始化的建议是: CFoo::CFoo(const CFoo& rhs) : m_obj(rhs.m_obj) {} 现在,主拷贝构造用初始化例程调用成员对象的拷贝构造,并且 m_obj 只被其拷贝构造初始化一次。通常情况下,拷贝构造应该调用其成员的拷贝构造。赋值也是如此。并且,它也同样适用于基类:派生类的拷贝构造和赋值操作应该调用对应的基类方法。当然,有时因为一些具体情况,可能你的做法会有所不同——这里我所描述的是通用规则,只有在你遇到强制性原因时才会破坏这个规则。如果你要在基本对象被初始化之后完成一些公共任务,可以将它们放到一个公共的初始化方法中,并在构造函数和 operator= 中调用。 Sunil Peddi 我有一个用 C#(用户界面)和经典的 C++(业务逻辑)写的应用程序。现在我需要从某个用 C++ 写的 DLL中调用一个函数(或方法),该函数在一个用 Visual C++ .NET 编写的 DLL 中。而这个 Visual C++ .NET DLL 又要调用另一个用 C# 写的 DLL。Visual C++ .NET DLL 相当于一个代理。这样做可行吗?我能用 LoadLibrary 调用 Visual C++ .NET DLL 输出的函数,可以得到返回值,但当我试图向 Visual C++ .NET DLL 中的函数传递参数时,我遇到如下错误:Run-Time Error Check Failure #0—The value |