
C++
rommi
这个作者很懒,什么都没留下…
展开
-
C++对象模型 多重继承与虚函数表
一 多重继承1) 代码:Code#include iostream>using namespace std;class B1{public: int x; virtual void v1(){ cout "B1::v1" endl; } void f1(){cout "B1::f1" endl; }};class B2{public: int y; v转载 2010-04-27 13:14:00 · 1066 阅读 · 0 评论 -
让类实现引用技术(1)
通过添加一个内部类来实现原创 2010-12-02 14:41:00 · 835 阅读 · 0 评论 -
直接初始化 和 复制初始化 的细微差别
<br />直接初始化 Object obj1(obj2);<br />复制初始化 Object obj1 = obj2;<br /> <br /> <br />区别<br />1. 一般情况下都调用copy constructor<br /> <br />2. 如果obj2 和obj1 不是一个类型(父类和子类),并且定了乐explicit构造函数 那么直接初始化会调用这个constructor<br />#include <iostream>using namespace std;cl原创 2010-12-03 14:18:00 · 1020 阅读 · 0 评论 -
Effective C++ 总结1 从C转向C++(条款1 - 4)
<br />1. 尽量用const和inline而不用#define<br /> 尽量用编译器而不用预处理<br /> <br />2. 尽量用<iostream>而不用<stdio.h><br /> <br />3. 尽量用new和delete而不用malloc和free<br /> new和delete可以这么有效地与构造函数和析构函数交互<br /> 可能存在的问题:比如有一个函数GetMemory()返回一个动态内存,由调用者负责释放,但是调用者不知道应该用free还是delete原创 2010-12-06 13:57:00 · 713 阅读 · 0 评论 -
Effective C++ 总结1 从C转向C++(条款1 - 4)
<br />1. 尽量用const和inline而不用#define<br /> 尽量用编译器而不用预处理<br /> <br />2. 尽量用<iostream>而不用<stdio.h><br /> <br />3. 尽量用new和delete而不用malloc和free<br /> new和delete可以这么有效地与构造函数和析构函数交互<br /> 可能存在的问题:比如有一个函数GetMemory()返回一个动态内存,由调用者负责释放,但是调用者不知道应该用free还是delete原创 2010-12-06 13:59:00 · 547 阅读 · 0 评论 -
Effective C++ 总结3 构造函数,析构函数和赋值操作符 (条款11 - 17)
<br />11. 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符<br />1) 原因:如果不写copy constuctor和operator =, 如果类中含有指针准备指向动态内存,那么在copy或者=的时候会造成2个指针指向同一个对象(bitwise bopy)<br />2) 当实现拷贝构造函数和赋值操作符非常麻烦的时候,特别是可以确信程序中不会做拷贝和赋值操作的时候,可以只声明这些函数(声明为private成员)而不去定义(实现)它们.<br /> <br /> <br />12.原创 2010-12-06 17:32:00 · 625 阅读 · 0 评论 -
Effective C++ 总结4 类和函数:设计与声明 (条款18 - 28)
<br />18. 争取使类的接口完整并且最小<br />1) 一个完整的接口是指那种允许用户做他们想做的任何合理的事情的接口<br />2) 一个最小的接口,是指那种函数尽可能少、每两个函数都没有重叠功能的接口<br /> <br /> <br />19. 分清成员函数,非成员函数和友元函数<br />1) <br />class rational {<br />public:<br /> ...<br /> const rational operator*(const rational& rhs)原创 2010-12-07 11:22:00 · 587 阅读 · 0 评论 -
Effective C++ 总结1 从C转向C++(条款1 - 4)
<br />1. 尽量用const和inline而不用#define<br /> 尽量用编译器而不用预处理<br /> <br />2. 尽量用<iostream>而不用<stdio.h><br /> <br />3. 尽量用new和delete而不用malloc和free<br /> new和delete可以这么有效地与构造函数和析构函数交互<br /> 可能存在的问题:比如有一个函数GetMemory()返回一个动态内存,由调用者负责释放,但是调用者不知道应该用free还是delete原创 2010-12-06 14:02:00 · 627 阅读 · 0 评论 -
析构函数不能抛出异常
<br />1、构造函数可以抛出异常。<br />2、c++标准指明析构函数不能、也不应该抛出异常。<br />more effective c++关于第2点提出两点理由:<br />1)如果析构函数抛出异常,则异常点之后的程序不会执行,如果析构函数在异常点之后执行了某些必要的动作比如释放某些资源,则这些动作不会执行,会造成诸如资源泄漏的问题。<br />2)通常异常发生时,c++的机制会调用已经构造对象的析构函数来释放资源,此时若析构函数本身也抛出异常,则前一个异常尚未处理,又有新的异常,会造成程序崩溃的原创 2010-11-19 16:02:00 · 2740 阅读 · 0 评论 -
C++ placement new
<br />placement new的作用就是:创建对象(调用该类的构造函数)但是不分配内存,而是在已有的内存块上面创建对象。用于需要反复创建并删除的对象上,可以降低分配释放内存的性能消耗。<br />#include <new> 定义头文件; <br />placement new。和其他普通的new不同的是,它在括号里多了另外一个参数。比如: <br />Widget * p = new Widget; //ordinary new 普通的<br />pi = new (ptr) int;转载 2010-11-22 10:15:00 · 965 阅读 · 0 评论 -
C++ 异常处理 要点
<br />1. throw出来的异常如果到最后也没有被catch,那么程序会abort<br />2. 构造函数中如何有异常抛出,那么这个类的析构函数不会被调用(因为这个对象没有构造完成),所以必须在构造函数中catch这个异常,然后释放之前所有已经分配的空间<br />3. 析构函数中的异常不能传递到析构函数外, 因为1. 之后的代码不会被执行(可能造成内存泄漏) 2. 有可能是因为一个异常处理进入的析构函数,如果再抛出异常,会导致程序直接abort.<br />4. 传递异常的时候应该只使用throw原创 2010-11-21 10:14:00 · 975 阅读 · 0 评论 -
exit with code 1073740791(0xc0000409)
<br />现象<br />The thread 'xxxx' (0xa78) has exited with code -1073740791 (0xc0000409).<br />程序直接退出 无debug信息<br /> <br />原因<br />Basicaly, error code 0xc0000409 indicates the system detects an overrun of a stack-based buffer in the application.原创 2011-05-31 16:49:00 · 10938 阅读 · 1 评论 -
static lib中全局变量初始化问题
<br />在我自己写的一个工厂类实现中,每个产品会注册创建接口到这个工厂类。工厂类使用这些<br />注册进来的创建接口来完成产品的创建。其结构大致如下:<br />product *factory::create( long product_type )<br />{<br /> creator c = m_creators[product_type];<br /> return c();<br />}<br />factory::instance().register(转载 2011-04-20 16:40:00 · 2749 阅读 · 0 评论 -
算术右移 vs 逻辑右移
算术右移 高位补符号位 逻辑右移 高位补0vs gcc都是算术右移 不建议对有符号数进行右移原创 2011-07-13 17:22:59 · 1210 阅读 · 0 评论 -
More Effective C++总结(1):基础议题
条款1: 区分指针和引用指针和引用的区别: 1) 引用不占用内存,指针占用内存(4Byte)2) 不存在空引用,引用必须要指代某个对象3) 指针可以赋新值,引用永远指向初始化时指向的对象.[] 操作符应该返回引用.条款2: 优先原创 2011-09-19 13:42:49 · 617 阅读 · 0 评论 -
More Effective C++总结(2):运算符
条款5: 小心用户自定义的转换函数两种函数可以让编译器实施隐式转换1) 单个参数的构造函数2) 隐式类型转换运算符 例: operator double() const避免编译器实施隐式转换的方法1) 对于单参数构造函数,使用explicit关键字原创 2011-09-19 14:53:37 · 598 阅读 · 0 评论 -
More Effective C++总结(3):异常
条款9: 使用析构函数防止资源泄漏下面代码会产生的问题:pa->processAdoption()可能抛出异常,导致delete不被执行void processAdoption(istream& datasource){ while(datasource)原创 2011-09-20 15:31:46 · 824 阅读 · 0 评论 -
函数对象 function object
函数对象(也称“算符”)是重载了“()”操作符的普通类对象.尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“算符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。 用函数对象代替函数指针有几个优点,首先,因为对象可以在内部修改而不用改动外部接口,因此设计更灵活,更富有弹性。函数对象也具备有存储先前调用结果的数据成员。在使用普通函数时需要将先前调用的结果存储在全程或者本地静态变量中,但是全程或者本地静态变量有转载 2010-12-02 11:16:00 · 903 阅读 · 0 评论 -
Effective C++ 总结1 从C转向C++(条款1 - 4)
<br />1. 尽量用const和inline而不用#define<br /> 尽量用编译器而不用预处理<br /> <br />2. 尽量用<iostream>而不用<stdio.h><br /> <br />3. 尽量用new和delete而不用malloc和free<br /> new和delete可以这么有效地与构造函数和析构函数交互<br /> 可能存在的问题:比如有一个函数GetMemory()返回一个动态内存,由调用者负责释放,但是调用者不知道应该用free还是delete原创 2010-12-06 14:01:00 · 612 阅读 · 0 评论 -
动态内存要点
1. 如果函数的参数是一个指针,不能用该指针去申请动态内存 错误代码void GetMemory(char* p, int count){ p = (char*)malloc(sizeof(char) * count);}int main(){ char* str = NULL; GetMemory(str,10); r原创 2010-05-05 15:00:00 · 480 阅读 · 0 评论 -
memcpy 实现要点
void* memcpy(void* dest, const void* src, size_t size){ const char* pSrc = static_cast(src); char* pDest = static_cast(dest); if(pSrc == NULL || pDest == NULL) return NULL; // 要点 考虑内存原创 2010-05-07 17:23:00 · 538 阅读 · 0 评论 -
stdcall 和 cdecl
_stdcall 是Standard Call的缩写,是C++的标准调用方式:1) 所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是this指针。2) 这些堆栈中的参数由被调用的 函数在返回后清除,使用的指令是 retn X,X表示参数占用的字节数,CPU在ret之后自动弹出X个字节的堆栈空间。称为自动清栈。3) 函数在编译的时候就必须确定参数个数,并且调用者必须严格的 控制参数的生成,不能多,不能少,否则返回后会出错。int function(int a,int b)int __stdca转载 2010-07-21 13:29:00 · 834 阅读 · 0 评论 -
auto_ptr 智能指针要点
1 构造函数与析构函数auto_ptr在构造时获取对某个对象的所有权(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性:int* p = new int(0);auto_ptr ap(p);从此我们不必关心应该何时释放p, 也不用担心发生异常会有内存泄漏。这里我们有几点要注意:1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样:int* p = new int(0)原创 2010-07-21 16:06:00 · 500 阅读 · 0 评论 -
指针 引用 const
1. 引用必须初始化 const 引用可以用不同类型的对象初始化(只要能从一种类型转换到另一种类型即可),也可以是不可寻址的值,如文字常量const int &ir = 1024; //rightint &r = 1024; //wrong2. const引用只是表明,保证不会通过此引用间接的改变被引用的对象! 通常用于函数参数 相当于void function(const char& value){}void function(const char* const v原创 2010-06-03 15:37:00 · 573 阅读 · 0 评论 -
STL 算法基本概念
<br />算法: 不是容器类的成员函数 是搭配迭代器使用的全局函数<br /> <br /> <br />iter = min_element(coll.begin(), coll.end());<br />iter = max_element(coll.begin(), coll.end());<br />sort(coll.begin(), coll.end());<br />iter = find(coll.begin(), coll.end());<br />reverse(iter, coll.原创 2010-07-30 15:27:00 · 563 阅读 · 1 评论 -
STL 容器和迭代器基础
容器1. 序列式容器 每个元素都有固定的位置 1) vector dynamic array 在尾部存取速度快 其他位置速度慢 因为要移动元素 push_back() pop_back() 2) deque dynamic array 在头部和尾部存取速度快 其他位置速度慢 因为要移动元素 push_back() push_front() pop_back() pop_front() 3) list doubly l原创 2010-07-30 14:57:00 · 585 阅读 · 0 评论 -
回调函数 基本思想和实现
回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回调,必须首先定义函数指针。void MyCallBack(){ printf("This is my call back function!");}bool MyCallBack(int n){ printf("This is my %d call back function!", n); return 0;}void(*pFun)();bool (*pFun2)(in原创 2010-06-07 17:01:00 · 517 阅读 · 0 评论 -
STL erase要点
<br />凡是非顺序容器 erase后 迭代器失效<br />原因:把非顺序容器的存储结构都想象成 链表 stl erase后返回的是当天容器对象 在链表元素被删除后 不可能通过原来指向此元素的指针来找到下一个对象<br /> <br />错误代码<br />int main(int argc, char* argv[]){ map<string, string> mapData; mapData["a"] = "aaa"; mapData["b"] = "原创 2010-08-09 16:50:00 · 543 阅读 · 0 评论 -
深入讨论C++的enum
呵呵,enum在实际中应用比较少,所以你会忽略它。但是,在这里,我告诉你,enum 和 struct、class一样,都是用户自定义类型。 对呀!enum是用户自定义类型,他有数据成员,还有成员函数!For example: enum e{a=1 , b=2 , c=4};那么: 001: enum e e1; //enum e不是对象,它是类型,e1才是类型enum的对象! 002: e e1; //e是类型enum e的简写哦!转载 2010-11-30 14:13:00 · 1327 阅读 · 1 评论 -
拷贝构造函数调用总结
<br />以下3种情况会调用拷贝构造函数<br />1. 在声明语句中用一个对象初始化另外一个对象<br />2. 函数参数值传递<br />3. 函数返回值值传递<br /> <br />对于1<br />MyClass my1;<br />MyClass my2 = my1; // 调用拷贝构造函数<br /> <br />在类中构造函数的初始化列表中 调用拷贝构造函数<br />但是直接在构造函数中写 调用 构造函数+赋值运算符 (构造函数和赋值运算符 分开调用)原创 2010-11-30 10:58:00 · 998 阅读 · 0 评论 -
C++拷贝构造函数的几个细节
<br />拷贝构造函数是C++最基础的概念之一,大家自认为对拷贝构造函数了解么?请大家先回答一下三个问题:<br />1. 以下函数哪个是拷贝构造函数,为什么?X::X(const X&); X::X(X); X::X(X&, int a=1); X::X(X&, int a=1, b=2); <br /> 2. 一个类中可以存在多于一个的拷贝构造函数吗?<br />3. 写出以下程序段的输出结果, 并说明为什么?如果你都能回答无误的话,那么你已经对拷贝构造函数有了相当的了解。#in转载 2010-11-30 11:06:00 · 917 阅读 · 0 评论 -
new delete全解析
<br />1. new operator (new操作符)<br /> 1) 分配空间 调用operator new<br /> 2) 调用构造函数<br /> <br /> Sample:<br /> string * ps = new string("Memory");<br /> <br />2. operator new<br /> 完全申明<br /> void* operator new(size_t size);<br /> 只负原创 2010-12-01 17:24:00 · 978 阅读 · 0 评论 -
智能指针
简单智能指针得实现 以及 auto_ptr存在的问题原创 2010-12-02 15:40:00 · 746 阅读 · 0 评论 -
关于构造函数的调用顺序
<br />在说构造函数之前我们得先弄明白几个问题,首先是什么是类的构造函数,什么是类的成员对象,什么是基类,然后我们再来说构造函数的调用顺序。<br /> 1、 类的构造函数<br /> 构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰,这就保证了它不仅什么也不用自动返回,而且根本不能有任何选择。构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用,一般方法在程序执行到它的时候被调用。一个类可以有多个构造函数,根据其参数个数的不同或参数类型的转载 2010-12-02 18:14:00 · 1014 阅读 · 0 评论 -
Template Specialization and Partial Template Specialization
<br />(1) 类模板特化<br />有时为了需要,针对特定的类型,需要对模板进行特化,也就是特殊处理.例如,stack类模板针对bool类型,因为实际上bool类型只需要一个二进制位,就可以对其进行存储,使用一个字或者一个字节都是浪费存储空间的.<br />template <class T><br />class stack {};<br />template < ><br />class stack<bool> { //…// };<br />上述定义中template < >告诉编转载 2010-12-03 13:56:00 · 1190 阅读 · 0 评论 -
C++ 构造函数抛出异常会引起内存泄漏吗?
C++ 构造函数抛出异常会引起内存泄漏吗? 我们用实际代码说明问题:先看一下如下代码:#include using namespace std;class Inner{public:Inner(){cout}~Inner(){cout}}; class Outer{private:int m_Value;Inn转载 2013-03-21 13:44:40 · 938 阅读 · 0 评论