C++不让显式调用构造函数,这里面有什么原因吗?

pgmsoul 2006-03-23 02:50:52
为什么C++不让显式调用构造函数.
...全文
1593 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
pgmsoul 2006-03-30
  • 打赏
  • 举报
回复
我想C++不让在外部显示调用构造函数是一种对这个特殊函数的保护措施.构造函数的本意就是在构造这个实例时初始化对象,多次调用是有害的.但本质上它就是一个函数,没有什么特殊的.
我之所以想要调用它是想构造自己的new(换一个名字),但是除了调用new没有办法调用构造函数.new是一个极特殊的函数,它不但可以调用构造函数,还可以传递不定个数的参数,依赖于具体的类型.
A::A()这种调用本质上是A a;但前者没有实例的名称,我不清楚C++的这个语法有什么用.
ox_thedarkness 2006-03-23
  • 打赏
  • 举报
回复
同意healer_kx(甘草) ( ) , replacement new 就是显式调用构造函数。

讨论下为什么不能调用构造函数 ——

///////////////////////////////////////////////////

比如这个定义:

class A{
public:
A();
explicit A( int );
};

我们也许希望默认构造函数 A::A() 依 A::A(int) 实现,以便减少冗余,比如:

A::A{
A( 0 ); // 失败!本语句产生局部对象 A(0),然后立即析构
}

假如C++支持这一点,那么本质就会象下面这样:

A::A{
new (this) A( 0 ); // 可以,但是不好
}

在这个做法基础上,我们可以考虑C++ 为什么不能显示调用构造函数。 C++中,类的成员是在进入构造函数之前初始化的,所以这样做可能造成成员被初始化两次:

class A{
B b;
public:
A();
explicit A( int );
};

A::A():b( ... ) { //初始化一次b
new (this) A( 0 ); // A::A(int)中又要初始化一次b
}

其中A的两个构造函数都必须初始化一次 A::b,造成混乱的局面(比如,你可能需要手动释放b然后 repleacement new, 否则可能资源泄漏等等 )。
healer_kx 2006-03-23
  • 打赏
  • 举报
回复
想显式调用构造函数,这么来。

#include <new.h>

MyClass* pClass = (MyClass*)malloc(sizeof(MyClass));
new (pClass) MyClass(); //显式地调用了。
password636 2006-03-23
  • 打赏
  • 举报
回复
是不让在外部,比如:
A a;
a.A();//非法.
但A的内部是可以的.
==================
用a.A::A()就可以了,但是如果你的A类提供了default constructor,这样的代码应该是调用了2次构造函数。
sjjf 2006-03-23
  • 打赏
  • 举报
回复
mark
shenmea00000 2006-03-23
  • 打赏
  • 举报
回复
这个是不是因为编译器的原因啊
class A{

A( int b );
}
int main()
{
A a(3);
}
不过C++编译器会在内部重写代码,会插入调用构造函数的代码,如下:
int main ()
{
A a;
a.A::A( 3 );
}
我只是举了个例子,希望你能看明白,最近正在看C++ Primer
刚好看到构造函数这一部分,上面是这么解释的,说:”类对象首次被使用之前,构造函数将被应用到该对象上“
希望对楼主有所帮助
yfgna 2006-03-23
  • 打赏
  • 举报
回复
觉得理解错了吧,应该可以的,楼上的就是一个例子啊
pgmsoul 2006-03-23
  • 打赏
  • 举报
回复
是不让在外部,比如:
A a;
a.A();//非法.
但A的内部是可以的.
Helloooooo 2006-03-23
  • 打赏
  • 举报
回复
是说不让啊?
class A{
public :
A(){ A(0);}
A(int i){
m_n = i;
}
private:
int m_n;
}
wqtl_357 2006-03-23
  • 打赏
  • 举报
回复
14.3.1 显式的析构调用
在某些程序情况下,有必要显示地对一个特殊类对象调用析构函数。这常常发生在和定
位new 操作符结合(placement operator new,见8.4 节讨论)的时候。让我们看一个例子,
当写:
char *arena = new char [ sizeof Image];
时,实际上我们已经分配了一个大小等于Image 型对象的新的堆存储区。相关联的内存
区没有被初始化,里面是上次使用之后的一段随机位序列。当我们写:
Image *ptr = new (arena) Image( “Quasimodo” )
时,没有新的内存被分配。相反,ptr 被赋值为与arena 相关联的地址,通过ptr,内存
被解释为一个Image 类对象。然而,虽然没有分配内存,但是构造函数被应用在现有的存储
区上。实际上,定位new 操作符允许我们在一个特定的、预分配的内存地址上构造一个类
对象。
当完成了Quasimodo 的图象(image)时,我们或许希望在由arena 指向的同一个内存
位置上操作一个Esmerelda 的图象(image)。一方面,我们知道怎样做:
Image *ptr = new (arena) Image( “Esmerelda” );
问题是,这样做覆盖了Quasimodo 的图像,我们已经修改了Quasimodo 的图像并希望
把它存储在磁盘上。一般我们通过Image 类的析构函数来做到这一点,但是如果应用操作符
delete
//不好:调用析构函数的同时也删除了存储区
delete ptr;
则除了调用析构函数,我们还删除了底层的堆存储区,这不是我们希望的。我们可以显
式地调用Image 的析构函数:
ptr -> ~ Image();
底层的存储区可以被后面的定位new 操作符调用继续使用。
尽管ptr 和arena 指向同一个堆存储区没有任何意义,但是,在arena 上应用delete 操作

//没有调用析构函数
delete arena;
不会导致调用Image 的析构函数,因为arena 的类型是char*。记住,只有当delete 表达
式中的指针指向一个带有析构函数的类类型时,编译器才会调用析构函数。
xiaocai0001 2006-03-23
  • 打赏
  • 举报
回复
>> 为什么C++不让显式调用构造函数.

此话从何说起?

64,677

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧