为什么不调用构造函数?

ID870177103 2015-06-02 01:37:45
众所周知,类构造后是没办法直接调用它的构造函数的,以至于需要placement new来欺骗编译器调用构造函数,或者提出构造函数的内容重新写一个函数

而且为什么编译器实现的operator=是通过构造一个临时对象然后调用默认的位拷贝operator=,而不是析构掉左值然后,以右值为参数调用左值的构造函数

c++11也没见有改动,到底这样设计到底有什么好处啊
...全文
269 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
ID870177103 2015-06-03
  • 打赏
  • 举报
回复
引用 7 楼 taodm的回复:
因为你只肯停留在语法层面看问题,而没有提高到语意层面思考编程语言的概念一致性与概念完整性。
具体说是什么语意?
pengzhixi 2015-06-03
  • 打赏
  • 举报
回复
标准说得很明白,你没提供这些特殊的构造函数,编译器在需要用到的时候就合成一个,但是不保证行为是你需要的。既然你都考虑到成员指针了。那么从语言的角度来说你就应该自己提供。
pengzhixi 2015-06-03
  • 打赏
  • 举报
回复
引用 4 楼 ID870177103 的回复:
[quote=引用 1 楼 pengzhixi 的回复:] 先不说编译器是不是这么做的,但是编译器为什么要像你说的先析构左边的,再调用构造函数在原来的位置上进行构造。这么费力不讨好的事它为什么要做。效果是不是你要的不说还拉低效率。
比如说类成员有指针,那就不能直接复制, 还是得调用析构之后,调用拷贝构造函数,既然你必须且已经实现了拷贝构造函数,为什么还要在实现一次拷贝构造函数呢 而且对普通的类,默认的拷贝构造函数就相当于memcpy,默认的析构函数就是什么都不做,编译器这样做又哪里拉低效率了呢[/quote] 有成员指针那么你就应该提供可靠的operator=,编译器并不知道你成员指针到底是否包含了动态分配的资源。你让编译器先调用析构函数这个不就是拉低效率么?人家直接位拷贝,你非让它先调用析构函数,你觉得会不会拉低效率呢?
lixin_4055 2015-06-03
  • 打赏
  • 举报
回复
确认一个问题
引用 楼主 ID870177103 的回复:
众所周知,类构造后是没办法直接调用它的构造函数的,以至于需要placement new来欺骗编译器调用构造函数,或者提出构造函数的内容重新写一个函数 而且为什么编译器实现的operator=是通过构造一个临时对象然后调用默认的位拷贝operator=,而不是析构掉左值然后,以右值为参数调用左值的构造函数 c++11也没见有改动,到底这样设计到底有什么好处啊
这里说的“类构造后是没办法直接调用它的构造函数的”貌似不那么正确 实际上
class A
{
};
A* a = new A();
new(a)A();
这样的写法是可以直接用的 再者delete a;之后再调用new(a)A()明显是内存越界操作了
ID870177103 2015-06-03
  • 打赏
  • 举报
回复
template<typename T>
friend inline T &operator= (T &a ,const T &b) {
	a.~T () ;
	new (&a) T (b) ;
	return a ;
}
让默认行为是这样 但是编译器默认不是这样,而且也不支持全局重载=
ID870177103 2015-06-03
  • 打赏
  • 举报
回复
inline void *__cdecl operator new (unsigned int size ,void *where) throw () {
	return where ;
}

template <typename T>
inline void memcpy (T &a ,const T &b) {
	const unsigned int i = sizeof (T) ;
	__asm {
		mov         ecx,i  
		mov         esi,[b]  
		mov         edi,[a]  
		rep movs    byte ptr es:[edi],byte ptr [esi]
	}
}

class A {
private :
	int i[10] ;
public :
	A () {i[0] = i[9] = -1 ;}
} ;

class B {
private :
	int i[10] ;
public :
	B () {i[0] = i[9] = -1 ;}
	inline B (const B &b) {
		memcpy<B> (*this ,b) ;
	}
	inline	~B () {}
	inline B &operator= (const B &b) {
		this->~B () ;
		new (this) B (b) ;
		return *this ;
	}
} ;

class C {
private :
	int (&i)[10] ;
public :
	C () :i (*(int (*)[10]) new int [10]) {i[0] = i[9] = -1 ;}
	C (const C &b) :i (*(int (*)[10]) new int [10]) {
		memcpy<int [10]> (i ,b.i) ;
	}
	~C () {delete [] &i ;}
	C &operator= (const C &b) {
		this->~C () ;
		new (this) C (b) ;
		return *this ;
	}
} ;


int main () {
	A a0 ,a1 ;
	B b0 ,b1 ;
	C c0 ,c1 ;
	a0 = a1 ;
	b0 = b1 ;
	c0 = c1 ;
	return 0 ;
}
看以上的operator=我希望编译器自动生成,而不是我自己写
ID870177103 2015-06-03
  • 打赏
  • 举报
回复
引用 10 楼 pengzhixi 的回复:
标准说得很明白,你没提供这些特殊的构造函数,编译器在需要用到的时候就合成一个,但是不保证行为是你需要的。既然你都考虑到成员指针了。那么从语言的角度来说你就应该自己提供。
上面打字打错了,我的意思是既然我实现了拷贝构造函数,那编译器生成默认的拷贝赋值函数为什么不用以实现的构造函数,而是继续位复制
taodm 2015-06-02
  • 打赏
  • 举报
回复
因为你只肯停留在语法层面看问题,而没有提高到语意层面思考编程语言的概念一致性与概念完整性。
ID870177103 2015-06-02
  • 打赏
  • 举报
回复
引用 3 楼 FightForProgrammer 的回复:
因为自己见识少,懂得太少了。。。。这么设计,恐怕需要很深入理解c++机制
具体什么机制?
ID870177103 2015-06-02
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
《深度探索C++对象模型》 《C++反汇编与逆向分析技术揭秘》 ?
里面有说明吗
ID870177103 2015-06-02
  • 打赏
  • 举报
回复
引用 1 楼 pengzhixi 的回复:
先不说编译器是不是这么做的,但是编译器为什么要像你说的先析构左边的,再调用构造函数在原来的位置上进行构造。这么费力不讨好的事它为什么要做。效果是不是你要的不说还拉低效率。
比如说类成员有指针,那就不能直接复制, 还是得调用析构之后,调用拷贝构造函数,既然你必须且已经实现了拷贝构造函数,为什么还要在实现一次拷贝构造函数呢 而且对普通的类,默认的拷贝构造函数就相当于memcpy,默认的析构函数就是什么都不做,编译器这样做又哪里拉低效率了呢
FightForProgrammer 2015-06-02
  • 打赏
  • 举报
回复
因为自己见识少,懂得太少了。。。。这么设计,恐怕需要很深入理解c++机制
赵4老师 2015-06-02
  • 打赏
  • 举报
回复
《深度探索C++对象模型》 《C++反汇编与逆向分析技术揭秘》 ?
pengzhixi 2015-06-02
  • 打赏
  • 举报
回复
先不说编译器是不是这么做的,但是编译器为什么要像你说的先析构左边的,再调用构造函数在原来的位置上进行构造。这么费力不讨好的事它为什么要做。效果是不是你要的不说还拉低效率。

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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