类成员运算符new,调用构造函数两次
class member operator new, calling constructor twice
有人知道为什么Latter语法调用Dog::operator new在完成分配后调用默认构造函数,最终调用2个构造函数?
我想知道我是否做错了什么,我该怎么做:
Dog *ptr = new("arg") Dog();
而不调用2个构造函数。并且不使用任何技巧,比如在对象已经构造好的情况下检查默认构造函数。这是代码:
class Dog
{
public:
Dog() // default
{
std::cout << "default Dog constructor [" << this << "]" << std::endl;
}
Dog(int x) // int argument
{
std::cout << "dog constructor int " << x << "[" << this << "]" << std::endl;
}
Dog(const std::string& word) // std::string argument
{
std::cout << "dog constructor std::string: " << word << " ["<< this << "]" << std::endl;
}
Dog(std::string &&word) // rvalue string argument
{
std::cout << "dog constructor std::string&& rvalue: " << word << " [" << this << "]" << std::endl;
}
// custom operator new
static void *operator new(std::size_t size) noexcept // for default constructor
{
Dog *ptr = (Dog*)malloc(size); // allocate memory
if (ptr) // if allocate ok
{
::new(ptr) Dog(); // call default constructor on object in memory
return ptr; // returns
}
else
return nullptr;
}
template<class T>
static void * operator new(std::size_t size, T&& value) noexcept // for argument constructor
{
Dog *ptr = (Dog*) malloc(size); // allocate the memory
if (ptr)
{
::new (ptr) Dog(std::forward<T>(value)); // pass the argument exactly as was passed to operator new,
// using perfect forwarding
return ptr;
}
else
return nullptr;
}
~Dog() { std::cout << "destructor " << std::endl; }
};
int main(void)
{
Dog *d = (Dog*) Dog::operator new(sizeof(Dog), "Const Char * Argument"); // argument version
Dog *d2 = (Dog*)Dog::operator new(sizeof(Dog)); // default constructor argument
//1 this works as expected, do what you specified in the member operator new, everything goes normal.
Dog *d3 = new Dog(); // default constructor
Dog *d4 = new("Const Char * Argument") Dog(); // argument constructor
// this is shorter, goes into your member operator new, BUT when it returns to this scope,
// call the default constructor for *d3, and for *d4 too.
// so this ends up calling constructors twice for both objects.
}
所以,我把分配和构造混合在一起,这里没有理由这样做,也许在运算符new[]中,用默认构造函数之外的构造函数来构造数组有一些用处。
但定义这些成员运营商的最佳方式是:
class Dog {
public:
// .......
// custom operator new
static void *operator new(std::size_t size) noexcept // for default constructor
{
void *memory = malloc(size); // allocate memory
if (memory) // if allocate ok
{
return memory; // returns
}
else
return nullptr;
}
static void *operator new[](std::size_t size) noexcept
{
void *memory = malloc(size); // allocate memory
if (memory) // if allocate ok
{
return memory; // returns
}
else
return nullptr;
}
static void operator delete(void *block) noexcept
{
free(block);
}
static void operator delete[](void *block) noexcept
{
free(block);
}
~Dog() { std::cout << "destructor " << std::endl; }
};
int main(void)
{
// now we can use new operator normaly without complications
Dog *d1 = new Dog[10]; // default constructor on all objects
Dog *d2 = new Dog("const char * argument"); // call std::string&& constructor
delete[] d1;
delete d2;
}
使用(关键字)new:它调用分配运算符new并(!)调用构造函数。
注意:当提供一个新的运营商时,你也应该提供一个运营商删除(在你的情况下,它会免费呼叫)。另外,不要忘记数组版本。
相关文章:
- 用相同的参数声明两个构造函数的最偶像化的方法是什么?
- pair的两个构造函数几乎相同,为什么不生成构建错误?
- 为什么<T> LLVM 中的预期为 Expect&&... 实现两个构造函数<T>?
- 为什么我的类只适用于两个构造函数 C++
- 两个构造函数(带和不带参数),没有输入 -> 没有参数运行。跳过上述类中的构造函数
- 类介绍 (c++) 项目希望我们创建两个构造函数,但它们都不需要任何参数 - 我应该在这里做什么?
- 除了两个构造函数外,C++库导入也可以工作
- 两次构造对象
- 在两个构造函数之前将我的静态数据成员在 CPP 文件中初始化为 0
- 如何有条件地在具有相同签名的两个构造函数之间切换
- RAII 在两个构造函数之间进行选择的方式
- 调用对数组引用两次的函数
- std::make_shared在VS2012中进行了两次构造函数调用
- 具有两个构造函数的抽象类
- 如何在c++中实现二次构造函数
- 这两个构造函数调用之间的区别
- 为什么在我的程序中调用两个构造函数
- 组合复制和移动的两个构造函数
- 为什么这两个构造函数一起不会产生歧义错误?
- C++两次传递函数指针导致问题