当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 拷贝构造和赋值操作符,C#和本机 C++ 代码的互用性

VC++
用VC实现支持多语言的程序
用鼠标手势动作来发送命令
在VC中使用MATLAB C/C++函数库
水晶报表在VC++6.0中的简单使用方法
关于限次软件的制作
可定制大小和数量的随机数函数
用vc.net实现记录开关机时间的程序
隐藏你的鼠标
一个黑客程序开发实例 -- IE终结者
修改QQ的程序
ACE自适配通信环境
超频软件原理探析
OutlookGrid:以Outlook样式分组和排列数据项(C#)
遍历和查找外部程序 Tree-View 中的项目
用 Win API 实现自绘按钮类
VC++ 6.0使用复选框和单选钮
对C#中的TreeView加背景图
在MFC中应用CTreeCtrl控件的技巧
CSortListCtrl 加强版
使用 VC.net 轻松实现按钮控件自绘

VC++ 中的 拷贝构造和赋值操作符,C#和本机 C++ 代码的互用性


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 97 ::
收藏到网摘: n/a

C++ At Work 专栏...
拷贝构造和赋值操作符,C#和本机 C++ 代码的互用性

原著:Paul DiLascia
翻译:NorthTibet

下载源代码:CAtWork0509.exe (276KB)
原文出处:Copy Constructors, Assignment Operators, and More

  • 拷贝构造,赋值操作符
  • C#和本机 C++ 代码的互用性

我有一个简单的 C++ 问题。我想让我的拷贝构造函数和赋值操作做同样的事情。你能告诉我最佳实现方法吗?

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 被初始化了两次!第一次是缺省构造,第二次是赋值时再次被初始化。嘿,这是怎么回事?
  在 C++ 中,赋值和拷贝是不同的,因为拷贝构造函数是对未初始化的内存进行初始化操作,而赋值是对现有的已经初始化的对象进行操作。如果你的类包含其它的类实例作为数据成员,那么拷贝构造在调用 operator=之前必须首先构造这些数据成员。其结果是致使这些成员就像 cctest 那样被初始化两次,明白了吗?当你用赋值操作而不是初始化例程进行成员初始化时,缺省构造函数也会发生同样的事情。例如:

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= 中调用。


你能告诉我如何从 C# 中调用 Visual C++ 类,对此我需要什么样的语法?

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