NTD*_*DLS 10 c++ class instantiation
我理解这可能被解释为"你的偏好是什么"问题之一,但我真的想知道为什么你会选择以下方法之一而不是另一种方法.
假设你有一个超级复杂的类,例如:
class CDoSomthing {
public:
CDoSomthing::CDoSomthing(char *sUserName, char *sPassword)
{
//Do somthing...
}
CDoSomthing::~CDoSomthing()
{
//Do somthing...
}
};
Run Code Online (Sandbox Code Playgroud)
我应该如何在全局函数中声明本地实例?
int main(void)
{
CDoSomthing *pDoSomthing = new CDoSomthing("UserName", "Password");
//Do somthing...
delete pDoSomthing;
}
Run Code Online (Sandbox Code Playgroud)
- 要么 -
int main(void)
{
CDoSomthing DoSomthing("UserName", "Password");
//Do somthing...
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*som 27
首选局部变量,除非您需要将对象的生命周期延伸到当前块之外.(局部变量是第二种选择).这比担心内存管理更容易.
PS如果你需要一个指针,因为你需要它传递给另一个函数,只需使用address-of运算符:
SomeFunction(&DoSomthing);
Run Code Online (Sandbox Code Playgroud)
Fra*_*nov 22
在堆栈上声明变量与堆中的变量时,有两个主要考虑因素 - 生命周期控制和资源管理.
当您严格控制对象的生命周期时,在堆栈上分配的效果非常好.这意味着您不会将该对象的指针或引用传递给本地函数范围之外的代码.这意味着,没有输出参数,没有COM调用,没有新线程.相当多的限制,但是在正常或异常退出当前作用域时,您可以正确地清理对象(尽管如此,您可能希望阅读使用虚拟析构函数的堆栈展开规则).堆栈分配的最大缺点 - 堆栈通常限制为4K或8K,因此您可能需要小心放置它.
另一方面,在堆上分配将需要您手动清理实例.这也意味着你有很多自由如何控制实例的生命周期.您需要在两种情况下执行此操作:a)您要将该对象传递出范围; 或者b)对象太大并且在堆栈上分配它可能导致堆栈溢出.
顺便说一下,这两者之间的一个很好的折衷方案是在堆上分配对象并在堆栈上为它分配一个智能指针.这可以确保您不会浪费宝贵的堆栈内存,同时仍然可以在范围退出时进行自动清理.
R. *_*des 13
第二种形式是所谓的RAII(资源获取是初始化)模式.它比第一个有许多优点.
使用时new,您必须delete自己使用,并保证它将永远被删除,即使抛出异常.你必须自己保证这一切.
如果使用第二种形式,当变量超出范围时,它将始终自动清除.如果抛出异常,堆栈会展开并清除它.
所以,你应该更喜欢RAII(第二种选择).
除了到目前为止所说的内容之外,还需要考虑其他性能因素,特别是在内存分配密集型应用程序中:
new将从堆中分配内存.在激烈(极其频繁)分配和解除分配的情况下,您将付出高昂的代价:
因此,当您需要短暂(或范围)时间段的对象时,一定要使用第二种方法(局部变量,在堆栈上.)如果您需要在线程之间共享数据,请使用new/malloc(一方面,您必须,另一方面,这些对象通常具有足够长的寿命,因此与堆管理器相比,您支付的成本基本上是0.)