class complex
{
float x,y;
public:
complex(){} //constructor with no arguments //what is use of giving such constructor
complex(float z){x=y=z;}//constructor with 1 argument.
complex(float real,float imag)
{x=real;y=imag;}
friend complex sum(complex,complex);
friend void show(complex);
};
complex sum(complex c1,complex c2)
{
complex c3;
c3.x=c1.x+c2.x;
c3.y=c1.y+c2.y;
return (c3);
}
void show (complex c)
{
cout<<c.x<<"+j"<<c.y<<"\n";
}
int main()
{
complex p,q,r;
p=complex(2.5,3.9);
q=complex(1.6,2.5);
r=sum(p,q);
cout<<"p=";show(p);
cout<<"q=";show(q);
cout<<"r=";show(r);
return 0;
}
答案 0 :(得分:22)
当您声明一个没有任何构造函数的类时,编译器会提供一个默认构造函数(按需),默认初始化成员。 (请注意,float
等内置函数的默认初始化不起作用。但是,一旦为类定义了任何构造函数,就不再自动提供默认构造函数。因此,如果您仍想要一个,则必须定义自己的默认构造函数。
答案 1 :(得分:11)
考虑空类:
class complex
{
float x,y;
};
编译器实际上为您生成了几个函数,即使它们未被声明。编译器生成的函数使类真正看起来像这样:
class complex
{
float x,y;
public:
complex(); //Compiler generated functions
complex(const complex&);
complex& operator=(const complex&);
~complex();
};
现在,您将学习复杂的类,然后使用float
添加构造函数。执行此操作时,告诉C ++您不希望编译器提供默认构造函数:
class complex
{
float x,y;
public:
// complex(); //No longer generated
//Don't forget explicit here unless you want implicit conversions
//from `float`
explicit complex(float z) {x=y=z;} //User defined constructor
/////////////////////////////////////////////////////////
//Compiler generated functions
complex(const complex&); //Note copy constructor and copy assignment
//operator are still generated.
complex& operator=(const complex&);
~complex();
};
现在,每当有人想要complex
时,他们必须提供float
参数。例如,以下代码现在是非法的:
int main()
{
complex c; //ERROR! No default constructor available.
complex g(4.2f); //Ok; float parameter specified.
}
如果您希望用户能够在不提供complex
参数的情况下构建float
,则必须显式创建构造函数:
class complex
{
float x,y;
public:
complex() {} //Allow default construction of `complex` objects.
//Don't forget explicit here unless you want implicit conversions
//from `float`
explicit complex(float z) {x=y=z;}
////////////////////////////////////////////////////////
complex(const complex&); //Compiler generated functions
complex& operator=(const complex&);
~complex();
};
现在,用户可以随意在任何地方默认构建complex
对象。
答案 2 :(得分:2)
因为有些程序员没有将他们的习惯升级到现代标准。
回到旧C天(C-99之前),必须在块的顶部声明变量,因此声明和初始化经常被分开。
在现代C ++中,几乎没有理由不在同一语句中声明和初始化。
因此,它应该是一个例外,而不是提供默认构造函数的规则。
答案 3 :(得分:1)
虽然我同意这样一个事实,即如果对它们没有规范意义,默认构造函数应该不受欢迎(复数应该有一个默认构造函数,使它们为零,模仿内置类型语义),有几个场景它们是强制性的。相当多的标准库构造要求默认的可构造对象,尤其是迭代器和容器的值类型(至少对于某些方法:例如resize
)。
有时,您可能希望对象(或标准强制要求)具有“null”状态,该状态只能由默认构造函数访问。然后你必须写safe bool idioms,使用智能指针和pimpl惯用语等。这可能是好的,也可能不是。
我同意,将无效状态的复杂性(以及它们可能导致的错误)添加到不需要它们的对象上并不是一个好习惯,但有时候,你不得不这样做。
对于记录,复杂的类应该如下:
struct complex
{
// Allow default initialization, and standard embedding
// of real numbers in complex numbers
complex(float real = 0., float imag = 0.)
: real(real), imag(imag)
{}
float real, imag; // no need for privacy here
};
// Operators are defined outside the class
complex operator+(complex x, complex y)
{
return complex(x.real + y.real, x.imag + y.imag);
}
// etc
std::ostream& operator<<(std::ostream& os, complex x)
{
return os << x.real << " + i" << x.imag;
}
请注意,由于complex
是POD类型,您甚至应该能够执行complex x = { 2., 3. };
并在静态数组中为它们进行零初始化。
答案 4 :(得分:0)
使用C ++标准库通常要求您的类具有无参数构造函数(如:vector<complex> vc(6);
)。
创建堆栈分配(complex arcmpl[20];
)或动态分配(complex * dynarcmplx = new complex[n];
)的数组以及调用no-arg构造函数。
如前所述,如果你为你的类定义任何构造函数,你就没有(编译器生成的no-arg)“默认构造函数”,在这种情况下,如果你想写上面提到的东西,你应该提供你自己的无参数构造函数。
答案 5 :(得分:0)
在您不希望在整个程序中使用该类的对象的情况下,有必要提供一个空的默认构造函数( private
)。
例如下面给出的类将使用编译器生成的默认空构造函数作为 public member
。结果,您可以创建此类的对象。
class test1
{
public:
int a;
};
int main()
{
test1 var; //compiles without an error.
}
但是,如果要阻止任何人构造该类的对象,则可以添加一个空的构造函数作为 private member
。例如。
class test2
{
test2(){}
public:
int a;
};
int main()
{
test2 var; // This will give an error
}
abc.cpp:在函数``主main()''中:abc.cpp:10:9:错误: “ test2 :: test2()”在此上下文中是私有的test2 var; // 这个 会给出一个错误 ^ ~~ abc.cpp:3:3:注意:此处声明为私有test2(){} ^ ~~~~
如果尝试运行上述程序,则会出现错误,因为从设计上来说'test2'类不应包含对象。