类的组合 构造函数的用法

一个类中内嵌另一个类的对象作为数据成员,称为类的组合。该内嵌对象称为对象成员,或者子对象。如三角形类Triangle类的内嵌Node类作为数据成员;

class Triangle
{
private:
    Node *nodei;  //对象成员
    Node *nodej;
    Node *nodem;
public:
    ...
};

在使用过程中,需要着重注意的是 对象成员的初始化!如Triangle的构造函数该如何定义?

如果一个类具有内嵌对象,那么在它对象化的时候既要对基本数据成员初始化也要对内嵌的对象成员初始化。

class X

{
  类名1  对象成员名1;
  类名2  对象成员名2;
  ...
  类名n  对象成员名n;
};

一般来说类X的构造函数定义形式为:

X::X(形参表0):对象成员名1(形参1),...,对象成员名n(形参n)
{

  类X的构造函数体

}

形参1到n一般来自形参表0;而且当调用构造函数的时候,首先按照在类的声明中的顺序依次调用对象成员函数的构造函数,对这些对象初始化,最后执行够赞函数体初始化类中的其他数据成员;析构函数的调用顺序与构造函数相反!举例说明:

#include<iostream>
using namespace std;
class Node
{
private:
    double x_;
    double y_;
public:
    Node(double x=0,double y=0)    //带默认参数的构造函数
    {
        x_=x;
        y_=y;
        cout<<"x="<<x_<<endl;
    }
    ~Node()                        //Node类的析构函数
    {
        cout<<"x="<<x_<<endl;
    }
};
class Triangle
{
private:
    Node nodei;
    Node nodej;
    Node nodem;
public:
    Triangle(double a1,double b1,double a2,double b2,double a3,double b3):nodei(a1,b1),
        nodej(a2,b2),nodem(a3,b3)//内嵌对象成员的Triangle类的构造函数定义
    {}
    ~Triangle()                     //Triangle类析构函数
    {}
};
int main()
{
    Triangle tri(1,1,2,2,3,3);     //初始化
    return 0;
}

输出结果:

 

说明:如果类的内嵌对象是用指针表示的,如何初始化呢?这个时候用上述的初始化列表就失效了!

#include<iostream>
using namespace std;
class Node
{
private:
    double x_;
    double y_;
public:
    Node(double x=0,double y=0)    //带默认参数的构造函数
    {
        x_=x;
        y_=y;
        cout<<"x="<<x_<<endl;
    }
    void init(double x,double y)//自定义初始化函数
    {
        x_=x;
        y_=y;
    }
    ~Node()                        //Node类的析构函数
    {
        cout<<"x="<<x_<<endl;
    }
    void disp(void)                //输出函数
    {
        cout<<"x="<<x_<<endl;
    }
};
class Triangle
{
private:
    Node *nodei;                //数据成员为指向Node类型的指针
    Node *nodej;
    Node *nodem;
public:
    Triangle(double a1,double b1,double a2,double b2,double a3,double b3)
    {
        Node *node1,*node2,*node3;    
        //定义参量指针
        node1=new Node;            //动态分配内存
        node2=new Node;
        node3=new Node;
        node1->init(a1,b1);        //调用自定义init()初始化三个点
        node2->init(a2,b2);
        node3->init(a3,b3);
        nodei=node1;            //再将初始化也即分配了内存后的指针值赋给数据成员
        nodej=node2;
        nodem=node3;
        nodei->disp();            //打印赋值结果
        nodej->disp();
        nodem->disp();
        //delete node3;            //释放指针所指
        //delete node2;
        //delete node1;

    }
    ~Triangle()                     //Triangle类析构函数
    {

    }
    void disp()
    {
        nodei->disp();
        nodej->disp();
        nodem->disp();
    }
};
int main()
{
    Triangle tri(1,1,2,2,3,3);     //初始化
    tri.disp();
    return 0;
}

输出结果为:

显然这样定义构造函数既不直观(不知道那个参数对应那个点)也很麻烦!改为如下:

#include<iostream>
using namespace std;
class Node
{
private:
    double x_;
    double y_;
public:
    Node(double x=0,double y=0)    //带默认参数的构造函数
    {
        x_=x;
        y_=y;
        cout<<"x="<<x_<<endl;
    }
    void init(double x,double y)//自定义初始化函数
    {
        x_=x;
        y_=y;
    }
    ~Node()                        //Node类的析构函数
    {
        cout<<"x="<<x_<<endl;
    }
    void disp(void)                //输出函数
    {
        cout<<"x="<<x_<<endl;
    }
};
class Triangle
{
private:
    Node *nodei;                //数据成员为指向Node类型的指针
    Node *nodej;
    Node *nodem;
public:
    Triangle(Node& node1,Node& node2,Node& node3)
    {
        //nodei=new Node;            //动态分配内存
        //nodej=new Node;
        //nodem=new Node;
        nodei=&node1;        //地址传递
        nodej=&node2;
        nodem=&node3;
        nodei->disp();            //打印赋值结果
        nodej->disp();
        nodem->disp();
        //delete node3;            //释放指针所指
        //delete node2;
        //delete node1;

    }
    ~Triangle()                     //Triangle类析构函数
    {

    }
    void disp()
    {
        nodei->disp();
        nodej->disp();
        nodem->disp();
    }
};
int main()
{
    Node nod1(1,1),nod2(2,2),nod3(3,3);
    Triangle tri(nod1,nod2,nod3);     //初始化
    //tri.disp();
    return 0;
}

输出:

这样来定义构造函数既没有用到init()自定义的初始化函数,而且物理意义明确。

 

总结:1.有子对象的类的初始化问题。子对象不是直接用类名表示,可以用初始化列表初始化。

   2.如果子对象用指针形式表示,就不能用初始化列表了。

 

转载于:https://www.cnblogs.com/mt-luo/p/4162524.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Java中,一个确实只能有一个构造函数具有与相同的名称。但是,您可以使用不同的参数列表来重载构造函数,这样可以创建多个构造函数。此外,您可以使用重载构造函数来提供不同的方式来初始化对象的属性。例如: ``` public class Person { private String name; private int age; public Person() { this.name = "Unknown"; this.age = 0; } public Person(String name) { this.name = name; this.age = 0; } public Person(int age) { this.name = "Unknown"; this.age = age; } public Person(String name, int age) { this.name = name; this.age = age; } } ``` 在上面的示例中,Person有四个构造函数,分别接受不同数量和型的参数。 ### 回答2: 一个只能包含一个构造函数构造函数是用来实例化对象时进行初始化操作的特殊方法。它的作用是创建对象的同时,对对象的成员变量进行赋初值,以确保对象在被创建后能够立即使用。 一个只能包含一个构造函数的原因是为了保证代码的清晰性和简洁性。如果一个中允许包含多个构造函数,那么在创建对象时,就需要根据不同的构造函数来调用相应的初始化操作。这样会增加代码的复杂度和理解难度,并且容易产生混淆和错误。 通过只能包含一个构造函数,可以使得初始化操作的逻辑更加明确和一致。同时,这也可以防止开发者滥用构造函数,将过多的逻辑放入其中,导致构造函数变得臃肿而难以维护。 然而,可以通过重载构造函数来达到不同的初始化需求。重载构造函数是指在一个中定义多个具有不同参数列表的构造函数。通过重载构造函数,可以根据不同的参数组合来初始化对象的不同成员变量,以满足不同的需求。 总结来说,一个只能包含一个构造函数是为了保证代码的简洁性和一致性。但是,可以通过重载构造函数来实现不同的初始化需求。 ### 回答3: 一个可以包含多个构造函数构造函数是一种特殊型的函数,用于创建和初始化对象时调用。它们与名称相同,没有返回型,并且可以在的内部定义。 在实际编程中,有时候可能需要根据不同的参数来创建对象。这时就可以使用重载构造函数的方式来创建不同版本的构造函数。重载构造函数允许我们在同一个中定义多个具有不同参数的构造函数,根据实际需要选择合适的构造函数来创建对象。 例如,有一个名为"Car"的,它有两个属性分别是"brand"和"color"。我们可以定义两个构造函数来创建该的对象。一个构造函数可能接受一个字符串型的参数来指定车的品牌,另一个构造函数可能接受两个字符串型的参数来指定品牌和颜色。这样,我们可以根据实际需要选择适合的构造函数来创建不同的车对象。 因此,一个可以包含多个构造函数,并且可以根据不同的参数来创建对象。这样可以提高灵活性,使得对象的创建更加方便和简洁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值