了解c++默默编写并vb调用vc编写的dll哪些函数

《Effective -C++》条款05了解C++默认编写并调用哪些函数_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
《Effective -C++》条款05了解C++默认编写并调用哪些函数
上传于|0|0|暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢花时间通读了下Meyers大神的著作《Effective c++》,其中受益很多,毕竟书中有很多东西是之前在写代码时完全没有考虑过的地方,作者用独到的眼光来告诉我们,c++不是一门简单的编程语言,而是一门堆积埃菲尔铁塔式程序的艺术。
接下来,让我对书中的“条款”用自己的语言方式,作一些总结和个人心得批注。
(PS:其中带“*”号的条款是本人不太理解或者令人可能较难理解的条款。对其中一些难以理解的条款我会给予详细解释,简单条款将略过)
Part1: 在写c++时,“让自己习惯c++”:
1.c++可以分为:(1)C (2)Object-Oriented C++
(3)Template C++ (4)STL。
2.尽量用const,enum,inline代替#define,或者说,宁可用编译器代替预处理器。因为宏定义容易出错(思考define函数进行运算时需要加上小括号)。
3.尽可能用const定义常量。
4.确定对象在使用前已先被初始化。特别对于构造函数,最好用成员初值列(member initialization list),而不是在构造函数内使用赋值。
举个例子:你有一个类A,那么在定义构造函数时,最好这样去初始化
cA:A(const string& name,const string& address,
const list&PhoneNumber&& phones):
theName(name),
thePhones(phones),
numTimesConsulted(0){}
这样的话,你无需对构造函数内部本身进行任何动作。理由在于,对大多数类型而言,这样比起调用默认构造函数高效许多。
Part2: 构造/析构/赋值运算
5.了解c++默默编写了和调用了哪些函数。
就是比如说说你要清楚,c++在编译时会拒绝哪些赋值动作,拒绝哪些?对于一个class,编译器会默认为类创建default构造函数、析构函数、copy构造函数、copy assignment操作符。
6.若不想用编译器自动生成的函数,就拒绝他。比如,你可以把一个类的复制构造函数放在private里,在子类继承他时,使用私有继承,让类uncopyable。
7.为多态基类声明virtual析构函数。
对于一个多态基类而言,应该对他声明一个virtual析构函数,就是说,假如一个类带有任何的virtual函数,我们就应该让他拥有一个virtual析构函数。
8.不要让析构函数吐出异常。如果有必要,那么在class中提供一个普通函数执行该操作。
9.绝对不要在构造和析构函数中调用virtual函数。
*10.令operatior=返回一个reference to *this。
cclass Widget{
Widget& operator+=(const Widget& rhs) //返回类型是个reference,指向当前对象
11.在operator=中处理“自我赋值”。你不能保证用户不会让对象做自我赋值这种看起来虽然愚蠢的事情。
*12.确保复制对象时没有忘记他的每一个成员。包括所有的公有与私有成员。
Part3: 资源管理
13.用对象来管理资源。
这里推崇一个概念--RAII(Resource Acquisition Is Initialization),你在获得获得一个对象时,必须对他进行相应有效的管理,使用STL提供的auto_ptr或者shared_ptr能让你更加轻松使用对象。推荐使用shared_ptr,无须担心复制动作带来的麻烦。
*14.小心资源管理的copy行为。
--对RAII对象做到禁止复制。
--对底层资源使用引用计数法(reference-count),比如在写锁操作时。
--对复制操作进行深拷贝(考虑堆的深复制)。
--转移底层资源的所有权。当一个对象被复制,资源的拥有权将从被复制的对象转移到目标对象上。
*15.在资源管理类中提供对原始资源的访问。
16.new与delete时采用相同形式。
S *s1 = new S;
S *s2 = new S[100];
delete []s2;
*17.以独立语句将newed对象储存于智能指针中。
int priority();
void processWidget(std::tr1::shared_ptr&Widget& pw, int priority);
//现在调用processWidget
processWidget(new Widget, priority());
现在你会发现这个代码无法通过编译,因为tr1::shared_ptr需要一个原始指针,但他的构造函数是个explict构造函数。
现在你把他修改成:
processWidget(std::tr1::shared_ptr&Widget&(new Widget), priority());
但是,这样会有很大可能导致内存泄漏。
思考,当我们对priority的调用失败时,我们无法阻止内存泄漏的产生!
避免方案其实很简单,就如下,用一个独立语句拆分他。
std::tr1::shared_ptr&Widget& pw(new Widget);
processWidget(pw, priority());
Part4: 设计与声明
18.让接口容易被正确使用,不易被误用。
*19.设计class犹如设计type。
20.宁用pass-by-reference-to-const代替pass-by-value
class Person(){
virtual ~Person();
class Student():public Person{
Student();
~Student();
string schoolN
string schoolA
bool validateStudent(Student s);
bool platoIsOk = validateStudent(plato);
当你用这个方法去传递一个Student对象时,总体成本是六次构造函数和六次析构函数。(自己算下string对象和student对象的创造过程)
(未完待续,最近实习入职,有时间继续写)
你可能感兴趣的文章
11 收藏,1.3k
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
分享到微博?
技术专栏,帮你记录编程中的点滴,提升你对技术的理解收藏感兴趣的文章,丰富自己的知识库
明天提醒我
我要该,理由是:
扫扫下载 App
SegmentFault
一起探索更多未知一个空的类,当编译器处理过之后,就包含:
一个copy构造函数
一个重载赋值操作符
一个析构函数
一个默认构造函数
class Empty()
// 声明一个空的类
class Empty()
// 经过编译器处理后
Empty() { ... }
Empty(const Empty& rhs) { ... }
~Empty() { ... }
Empty& operator=(const Empty& rhs) { ... }
需要注意的一点是,只有当这些函数被需要时,它们才会被编译器创建出来。
现在我们知道了,编译器会为我们创建这些函数。
下面举个例子引入今天的重点问题:
如果编译器拒绝为我们做这些事情了,就麻烦了。那么,编译器什么情况下会拒绝为我们做这些事情呢?
class Empty()
// 声明一个空的类
class Empty()
// 经过编译器处理后
Empty() { ... }
Empty(const Empty& rhs) { ... }
~Empty() { ... }
Empty& operator=(const Empty& rhs) { ... }
类NameObject并没有给我们重载赋值操作符,哪门这个编译器会给我提供这个操作吗,如果提供了这个操作,那么Demo中的p最后的成员的值是什么呢?让我们慢慢来分析一下:
1 p.nameValue
C++规定:不可以让reference改指向不同的对象。
因此,C++对这种情况是拒绝编译这一行的赋值动作。即如果你打算在一个有reference成员的class内支持重载赋值操作,那么你必须自己定义重载赋值操作符。
2 p.objectValue
对于const成员变量,更改const变量是不合法的,所以编译器同样拒绝为你创建这个赋值操作。
3 还有一个情况会导致编译器&罢工&
如果某个base classes将重载赋值操作符声明为private。
原因:子类中的重载赋值操作符会默认去调用基类中的赋值操作符。
编译器可以暗自为你创建默认构造函数、拷贝构造函数、重载赋值操作符,以及析构函数。
但是需要注意那些编译器拒绝你的情况。
《Effective C++ 3rd》
阅读(...) 评论()构造函数执行原理
作者 : 卿笃军
构造函数 ,是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。(这句话来自百度百科)
由上面这句话,我们知道:构造函数,是用来给对象开辟空间并初始化对象的~~~~~
那么,构造函数具体是如何执行的呢?下面附上一张图,图解构造函数执行过程:
第一步:构造函数接收到主函数传进来的参数,图中①。
vcD4KPHA+tdq2/rK9o7q4+b7dcHJpdmF0ZTogwO/D5rPJ1LGx5MG/tcS2qNLly7PQ8qOsuPi21M/zv6qx2b/VvOSjrM281tCi2qGjPC9wPgo8cD48YnI+CjwvcD4KPHA+tdrI/bK9o7q9+NDQ" : "号后面的初始化工作,其中初始化顺序为:private:成员变量定义顺序,即先m_a,再m_b,图中③。
(和" : "后面的顺序无关。这里可以想象成去医院看病,只和你预约的先后有关,和你排队的顺序无关,先预约的先看病)。
第四步: 执行{ } 里面的cout<<语句,图中④。
class GZHS
GZHS(int a = 0, int b = 0) : m_b(b), m_a(a)
cout<<m_a<<","<<m_b<<
int main()
GZHS Test(5,22);
参考文献:百度百科,构造函数,/view/411124.htm,日
熊思的CSDN博客,C&#43;&#43;的构造函数,http://blog.csdn.net/u/article/details/14年5月22日

我要回帖

更多关于 vs2008 dll 编写调用 的文章

 

随机推荐