类的组合 构造函数的用法

在一个类中内嵌另一个类的对象作为数据成员,称为类的组合。该内嵌对象称为对象成员,或者子对象。如三角形类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.如果子对象用指针形式表示,就不能用初始化列表了。

时间: 2025-01-13 17:52:07

类的组合 构造函数的用法的相关文章

类的组合

1.类的组合:类中的成员数据是另一个类的对象.类组合的构造函数:原则:不仅要负责对本类中的基本类型成员数据赋初值,也要对对象成员初始化. 2.构造函数的调用顺序: 1.调用内嵌对象的构造函数(按内嵌时的声明顺序,先声明者先构造): 2.调用本类的构造函数 3.析构函数的调用顺序: 1.调用本类的析构函数: 2.调用内嵌对象的析构函数(按内嵌时的声明顺序,先声明者先析构). 4.若调用默认构造函数(即无形参的),则内嵌对象的初始化也将调用相应的默认构造函数. 5.类声明的方式有两种:使用前向引用声

【C++基础】类的组合

所谓类的组合是指:类中的成员数据是还有一个类的对象或者是还有一个类的指针或引用.通过类的组合能够在已有的抽象的基础上实现更复杂的抽象. 比如: 1.按值组合 #include<iostream.h> #include<math.h> class Point { public: Point(int xx,int yy)//构造函数 { x=xx; y=yy; cout<<"Point's constructor was called"<<e

PHP构造函数的用法分析

管理 随笔- 1 文章- 1 评论- 0 PHP构造函数的用法分析 PHP构造函数的声明与其它操作的声明一样,只是其名称必须是__construct( ).这是PHP5中的变化,以前的版本中,构造函数的名称必须与类名相同,这种在PHP5中仍然可以用,但现在以经很少有人用了,这样做的好处是可以使构造函数独立于类名,当类名发生改变时不需要改相应的构造函数名称了.为了向下兼容,如果一个类中没有名为__construct( )的方法,PHP将搜索一个php4中的写法,与类名相同名的构造方法.格式:fun

初学C++-----------------类的组合

类的组合: 新类中的数据成员是另一个类的对象,可称这种成员是新建类的子对象或对象成员. 可以在已有的抽象的基础上实现更复杂的抽象. 新类的定义格式可表述为: class X { 类名1  成员1: 类名2  成员2: ........ 类名N  成员N: .......... }; 对象成员的初始化: 在构造类X的对象过程中: 系统首先调用其子对象的构造函数,初始化子对象:然后才执行类X自己的构造函数的函数体以完成初始化本类中的非对象成员. 对于同一类中的不同的子对象,系统按照它们在类中的说明顺

类的组合使用

4.类的组合使用: 类的组合使用,就是类里边的实例变量是自己定义的类.用法与普通类使用一样. 例子: family.h #import <Foundation/Foundation.h> #import "Father.h" #import "Mother.h" #import "Son.h" @interface Family : NSObject{ //father Father *_father; //mother Mother

C++ Primer 学习笔记_52_类与数据抽象 --构造函数【下】

类 --构造函数[下] 二.默认实参与构造函数 一个重载构造函数: Sales_item():units_sold(0),revenue(0){} Sales_item(const std::string &book): isbn(book),units_sold(0),revenue(0) {} 可以通过给string初始化式提供一个默认实参将这些构造函数组合起来: Sales_item(const string &book = " "): isbn(book),un

浅谈类的组合

4. 类的组合 4.1 定义 类中的成员数据是另一个类的对象 4.2 类组合的构造函数设计原则 不仅要负责对本类中基本类型成员数据初始化,也要对对象成员初始化. 4.3 声明形式 类名::类名(对象成员所需的形参,本类成员形参):对象1(参数),对象2(参数),....... {  // 函数体其他语句 } 4.4 例子:类的组合,线段类. #include<iostream> #include<cmath> Using namespace std; Class Point{ Pu

c++,类的组合

1. 在A类中以B类的对象作为成员变量,称为类的组合(composition). 2. 在组合时,一般在A类的构造函数初始化列表中要初始化B类(会调用B类的一个构造函数), 如果没有初始化B类,则会调用B类中可以不传参数的构造函数. #include <iostream> using namespace std; #include <string> //-------------------------------------- class A { public: int m_ax

C++类的组合

序:都说书写是为了更好地思考,最近在学习c++编程设计,之前在博客园上看到的各位大神们的随笔,心中充满各种羡慕嫉妒,怎么都写得这么好.为此在摸索良久后,终于在今天开启了自己的随笔之路.正文:c++类的组合,描述的是一个类内嵌入其他类的对象作为成员的情况,它们之间的关系式包含与被包含的关系.当创建类的时候,如果这个类具有内嵌对象成员,那么各个内嵌对象也将被自动创建.  在声明一个组合类的对象时,不仅它自身的构造函数将被调用,而且还将调用其内嵌对象的构造函数.构造函数的调用顺序为: ①按照内嵌对象在