Roger Luo

超越梦想一起飞
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C++ 常见问题

Posted on 2013-03-18 13:38  Roger Luo  阅读(302)  评论(0编辑  收藏  举报

Q:构造函数中涉及的大量内存分配以及复杂对象变量的初始化失败应该如何处理

应该放在initialize list里面

ClassA():objb(new ClassB)
这样如果失败了一些构造好的对象也会自动析构掉

有些方法:

ClassA::ClassA()
{
objb = new ClassB();
if(objb == NULL)
{
......
}
}
你这样根本不管用:
T* p1 = new T; // throws bad_alloc if it fails
T* p2 = new(nothrow) T; // returns 0 if it fails

失败的时候new的默认行为是抛出bac_alloc异常,可以参考标准

对于如下的类需要注意他的内部成员的order顺序

class myClass
{
private:
...
int m_nDataLength;
boost::shared_array<int> m_pData;
...

public:
myClass(): ..., m_nDataLength(10), m_pData(new int[m_nDataLength]), ...
{
}
}
如果改成
class myClass
{
private:
...
boost::shared_array<int> m_pData;
int m_nDataLength;
there will be a bug for compiler. Here is the detail reason for class member initialization: While the initialization in your example does happen in the order you want, it's not for the reason you assume: Initialization happens in the order of the data members declaration in the class definition. The reason for this is that the destructor must destroy the members in backward order not matter which constructor was used to create the object. For that, a constructor-independent way of defining the construction order must be used.

realloc(void *ptr, size_t new_size) requires the given area of memory that ptr points to to be previously allocated by malloc(), calloc() or realloc() and not yet freed with free(), otherwise, the results are undefined.

Use realloc only with malloc, calloc or another realloc and clean it up with free.
In C++ use always new with delete and new[] with delete[].

To new is C++; To malloc is C; To mix them is sin - CodeProject

The right option is probably to use a container that does the work for you, like std::vector.

new and delete cannot resize, because they allocate just enough memory to hold an object of the given type. The size of a given type will never change. There are new[] and delete[] but there's hardly ever a reason to use them.

What realloc does in C is likely to be just a malloc, memcpy and free, anyway, although memory managers are allowed to do something clever if there is enough contiguous free memory available.

Use ::std::vector!

Type* t = (Type*)malloc(sizeof(T)*n) 
memset(t, 0, sizeof(T)*m)

becomes

::std::vector<T> t(n, 0);

Then

t = (Type*)realloc(t, sizeof(T) * n2);

becomes

t.resize(n2);

If you want to pass pointer into function, instead of

Foo(t)

use

Foo(&t[0])

It it absolutely correct c++ code, because vector is a smart c-array.

=====================
Link2005 already defined
通常为dllexport中包含了全局变量,需要在此变量前添加static,使其定义只在该头文件中
 
C2059 syntax error : '__declspec(dllexport)' 
dlleport should be the first key word for global function
 
cppunit usage
dont put the cppunit assertion in the try catch block, otherwise the assertion could not be thown to cppunit processor.
 
字符串中查找子字符串
如果是case sensitive,就可以直接使用string::find
如果是case insensitive,就可以使用boost::ifind_first函数使用如下:
#include <boost/algorithm/string.hpp>

iterator_range<string::iterator> it;
it = boost::ifind_first(strTgr, strPattern);
if (it.empty() == true)
cout<<"Not found"<<endl;
else
cout<<"Found It"<<endl;

 

class ComplexA
{
public:
ComplexA(int len):_l(len), _p(new char[_l]){cout<<"ComplexA::ComplexA"<<endl;}
~ComplexA(){cout<<"ComplexA::~ComplexA"<<endl; if (_p != nullptr) delete _p;}
private:
int _l;
char * _p;
};
class ComplexB
{
public:
ComplexB(int len):_l(len), _p(new char[_l]){cout<<"ComplexB::ComplexB"<<endl;}
~ComplexB(){cout<<"ComplexB::~ComplexB"<<endl; if (_p != nullptr) delete _p;}
private:
int _l;
char * _p;
};
class ComplexC
{
public:
ComplexC(int len):_l(len), _p(new char[_l]){cout<<"ComplexC::ComplexC"<<endl;}
~ComplexC(){cout<<"ComplexC::~ComplexC"<<endl; if (_p != nullptr) delete _p;}
private:
int _l;
char * _p;
};
class Wrapper
{
public:
Wrapper(int lenA, int lenB, int lenC):pA(new ComplexA(lenA)), pB(new ComplexB(lenB)), pC(new ComplexC(lenC)){cout<<"Wrapper::Wrapper"<<endl;}
~Wrapper(){cout<<"Wrapper::~Wrapper"<<endl; if (pA) delete pA; if (pB)delete pB; if (pC)delete pC;}
private:
ComplexA * pA;
ComplexB * pB;
ComplexC * pC;
};