我有以下名为 DATA 的类。
enum DATATYPE{DATATYPE_CONSTANT=0, DATATYPE_NUMBER,DATATYPE_STRING, DATATYPE_MATRIX, DATATYPE_OBJECT};
struct DATA //A Data container for the variable
{
DATA(DATATYPE type,int row=0,int col=0)
{
m_str=0;m_number=0;
m_DataType=type;
if(type==DATATYPE_NUMBER) m_number=new double;
if(type==DATATYPE_STRING) m_str=new string("");
cout<<"In constructor"<<endl;
//if(type==DATATYPE_MATRIX) m_matrix= new MatrixXd(row,col);
}
~DATA()
{
if(m_str) m_str->clear();
if(m_number) {delete m_number; m_number=0;}
std::cout<<"In Destructor"<<std::endl;
//if(m_matrix) {delete m_matrix; m_matrix=0;}
}
DATA(const DATA& other)
{
m_number=other.m_number;
m_str=other.m_str;
m_DataType=other.m_DataType;
cout<<"In copy constructor"<<endl;
}
DATA& operator=(const DATA& other)
{
m_number=other.m_number;
m_str=other.m_str;
m_DataType=other.m_DataType;
cout<<"In operator="<<endl;
return *this;
}
DATATYPE GetType()
{
return m_DataType;
}
double* GetNumber()
{
return m_number;
}
void SetNumber(const double& val){*m_number=val;}
string* GetString()
{
return m_str;
}
private:
DATATYPE m_DataType;
string* m_str;
//MatrixXd* m_matrix;
double* m_number;
};
我有以下测试:
DATA GetData();
int main()
{
cout<<"Before GetData call"<<endl;
DATA dat=GetData();
//DATA dat2=dat;
cout<<*(dat.GetNumber())<<endl;
cout<<"After Get Data call"<<endl;
cout << "Exiting main" << endl;
return 0;
}
DATA GetData()
{
cout<<"In Get Data"<<endl;
DATA ret(DATATYPE_NUMBER);
double d=5;
ret.SetNumber(d);
cout<<"Exiting GetData"<<endl;
return ret;
}
运行测试后输出为:
Before GetData call
In Get Data
In constructor
Exiting GetData
5
After Get Data call
Exiting main
In Destructor
我有以下问题:
当我调用
DATA dat=GetData();
时,它既不调用构造函数、复制构造函数也不调用等于运算符。 dat对象是如何构造的。另外,编译器从GetData
返回时究竟做了什么?对于
DATA
结构,或者一般的聚合数据类型,用new
初始化成员变量总是一个好主意吗?当我初始化 sayDATA *d=new DATA(DATATYPE_NUMBER)
时,成员变量会发生什么?内存泄漏是否更容易出错?
最佳答案
问题一
当我调用 DATA dat=GetData();
时,它既不调用构造函数、复制构造函数也不调用等于运算符。 dat对象是如何构造的。另外,从 GetData
返回时,编译器究竟做了什么?
回答 这是返回值优化 (RVO) 的结果。您可以阅读更多关于它们的信息 here .
在 g++ 中,您可以使用标志 -fno-elide-constructors
禁用 RVO。如果您对代码执行此操作,您将看到来自复制构造函数的消息。
问题二
对于 DATA
结构,或者一般的聚合数据类型,用 new 初始化成员变量总是一个好主意吗?当我初始化 say DATA *d=new DATA(DATATYPE_NUMBER)
时,成员变量会发生什么?内存泄漏是否更容易出错?
回答
里面有3个问题。
回答 2.1
该问题的答案是“取决于您的应用程序”。对于某些人来说,将对象作为成员数据是有意义的,而对于其他人来说,将对象指针作为成员数据是有意义的。当你使用指向对象的指针时,你必须遵循 Rule of Three , 已成为 Rule of Five in C++11 .
回答 2.2
成员变量的初始化就像您使用它们一样:
Data d = DATA(DATATYPE_NUMBER);
回答 2.3
使用动态内存有好处,但也有缺点。任何时候使用动态内存分配,都会进入更容易出错的代码。你必须担心它潜在的不良副作用:
- 悬挂指针。
- 丢失指针。
- 访问超出分配的内存。
关于c++ - 返回对象时编译器做了什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24947323/