我想在下面的代码中将MyClass保存在堆栈内存中(更简单,更快),但是避免调用默认构造函数:
#include <iostream>
class MyClass {
public:
MyClass() {
std::cout << "MyClass()" << std::endl;
}
MyClass(int a) {
std::cout << "MyClass(" << a << ")" << std::endl;
}
MyClass(const std::string& a) {
std::cout << "MyClass(\"" << a << "\")" << std::endl;
}
void doStuff() {
std::cout << "doStuff()" << std::endl;
}
};
int main(int argc, char* argv[]) {
bool something;
if (argc > 1)
something = 1;
else
something = 0;
MyClass c;
if (something)
c = MyClass(1);
else
c = MyClass("string");
c.doStuff();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,避免调用默认构造函数的唯一方法是使用指针,但是我必须在堆中分配并处理内存管理.还有其他方法吗?
jxh*_*jxh 13
如果您不介意使用完全黑客,可以尝试放置new.
char mem[sizeof(MyClass)] alignas(MyClass);
auto custom_deleter = [](MyClass *p){ p->~MyClass(); };
std::shared_ptr<MyClass> c(new (mem) MyClass, custom_deleter);
Run Code Online (Sandbox Code Playgroud)
您可以使用它alignas来确保为您的对象正确对齐分配的自动内存.该custom_deleter函数调用析构函数而不释放内存,这在使用带智能指针的自动内存时是必需的.可在此处找到代码演示.
但是,对于您的问题,存在更优雅的解决方案.您可以使用复制构造函数:
MyClass c = something ? MyClass(1) : MyClass("string");
c.doStuff();
Run Code Online (Sandbox Code Playgroud)
你是对的.您不可能避免调用默认构造函数,除非您想复制一些代码,如下所示.
if (something) {
MyClass c(1);
c.doStuff();
}
else {
MyClass c("string");
c.doStuff();
}
Run Code Online (Sandbox Code Playgroud)
我建议您创建堆的对象,但将内存处理委托给另一个类.使用C++ 03,可以使用std :: auto_ptr类.对于C++ 11,不推荐使用auto_ptr,而是可以使用shared_ptr或unique_ptr.
以下是使用shared_ptr的一些示例代码 -
std::shared_ptr<MyClass> c;
if (something)
c.reset(new MyClass(1));
else
c.reset(new MyClass("string"));
c->doStuff();
Run Code Online (Sandbox Code Playgroud)
超出范围时,将自动删除该对象.
通常,建议使用智能指针而不是自己进行内存管理.当您处理可能抛出异常的代码时,这尤其有用.
本杰明Bannier的建议对我的作品在GCC 4.7.2,没有特殊的编译标志(即默认的优化),或-O0,-O1,-O2,或-O3:
int main(int argc, char* argv[]) {
bool something;
if (argc > 1)
something = 1;
else
something = 0;
MyClass c = something ? MyClass(1) : MyClass("string");
c.doStuff();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我在GCC 3.4.4(大约2004年),GCC 3.4.6(2006年),GCC 4.2.4(2007年)和GCC 4.7.2(2012年)上尝试时,我得到了相同的结果.
| 归档时间: |
|
| 查看次数: |
1753 次 |
| 最近记录: |