C++ 一个类成员函数调用另一个类成员的方法

在继承之外,在C++中一个类成员函数调用另一个类成员的方法主要有:类的组合,友元类,类的前向声明,单例模式等,下面主要讲讲这4种方法的实现

方法1:利用类的组合
组合通俗来讲就是类B有类A的属性,如声明一个Person类,再声明一个Teacher类,Person类对象有年龄和姓名成员,而Teacher类对象成员也有年龄和姓名属性,所以我们可以将类Person的对象作为类Teacher的成员变量,那么就实现了Teacher类对象也有这两个属性。如下所示:

#include<iostream>
#include<string>
using namespace std;

class Person
{
  public:
      Person(int _age, string _name) :age(_age), name(_name) {}
      ~Person() {};
    void print() 
    {
        cout << name<<"    " << age  << endl;
    }
    private:
        int age;
       string name;
};
class Teacher
{
public:
    Teacher(Person* _person) :person(_person) {}
    ~Teacher() {};
    void print()
    {
        this->person->print();
    }
    private:
        Person* person;
        
};

int main()
{
    Person p(40, "lisan");
    Teacher teacher(&p);
    teacher.print();
    system("pause");
    return 0;
}

方法2:友元类
友元类就是在类A中声明一个类B,那么就称类B是类A的友元类,这时类B的对象可以访问类A的一切成员,包括私有成员。如下所示:

#include<iostream>
#include<string>
using namespace std;

class A
{
public:
    friend class B;
    A(int _age, string _name) :age(_age), name(_name) {}
    ~A() {};
    void print_a()
    {
        cout << name << "    " << age << endl;
    }
private:
    int age;
    string name;
};
class B
{
public:
    B() {};
    ~B() {};
    void print_b(A& a)
    {
        a.print_a();
    }
};

int main()
{
    A a(20,"name");
    B b;
    b.print_b(a);
    system("pause");
    return 0;
}

注意:

友元类是单向的,即类B是类A的友元类,但类A不是类B的友元类
友元类不能传递,即类B是类A的友元类,类C是类B的友元类,但类C不是类A的友元类
3.前项声明
使用前面两种方法,如果将两个类在不同的头文件中声明,则需要在第二个类中包含第一个类的头文件,但使用类的前向声明则不用使用#include"xxx",具体实现如下:

代码段1:在person.h头文件
#pragma once
#ifndef _PERSON_H
#define _PERSON_H
#include <string>
#include <iostream>
class Person
{
public:
    Person(int _age, std::string _name) :age(_age), name(_name) {}
    ~Person() {};
    void print() const
    {
        std::cout << name << "    " << age << std::endl;
    }
private:
    int age;
    std::string name;
};

#endif

代码段2:在teacher.h头文件中
#pragma once
#ifndef _TEACHER_H
#define _TEACHER_H
//#include "person.h"   //前两种方法

class Person;  //类的前向声明
class Teacher
{
public:
    Teacher() {};
    ~Teacher() {};
    void print(Person& person)
    {
        person.print();
    }    
};
#endif

代码段3:主文件main.cpp
#include<iostream>
#include "person.h"
#include "teacher.h"
int main()
{
    Person p(40, "lisan");
    Teacher teacher;
    teacher.print(p);
    system("pause");
    return 0;
}

注意:

类的前向声明只能用于定义指针、引用、以及用于函数形参的指针和引用
前向声明的类是不完全的类型,因为只进行了声明而没有定义
前向声明的作用:

在预处理时,不需要包含#include"xxx",相对节约编译时间
方便的解决两种类类型互相使用的问题。
4.单例模式
单例模式是程序设计模式中最常用的模式之一,其主要思想是将类的构造函数声明为私有的防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的实现由一个public的类方法代劳,该方法返回单例类唯一的实例。
注意:

采用单例模式的对象在进程结束才被释放。
关于单例模式的详细内容大家可以去看单例模式的知识。下面是一个典型的单例例子:

#include<iostream>
#include<string>
using namespace std;

class Singleton 
{
public:
    static Singleton* getInstance()
    {
        instance =  new Singleton();
        return instance;
    }
    ~Singleton() {};
private:
    Singleton() {};
    static Singleton* instance;
};

下面看怎么在另一个类中使用单例模式实现成员函数的调用:

class Singleton
{
public:
    static Singleton* getInstance()
    {
        if (instance == nullptr)
        {
            instance = new Singleton();
            return instance;
        }
        else
            return  instance;
    }
    static void print_instance()
    {
        cout<<name <<" " <<age <<endl;
    }
    ~Singleton() {};
private:
    Singleton() {};
    static Singleton* instance;
    static int age;
    static string name;
};

int  Singleton::age = 20;
string Singleton::name = "lisan";
Singleton* Singleton::instance = nullptr;

class A
{

public:
    void print_a()
    {
         Singleton::getInstance()->print_instance();
    }

};
int main()
{
    A a;
    a.print_a();
    system("pause");
    return 0;
}
 

  • 12
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值