C++ 友元、组合、继承的简单使用

现在有这样一个问题,描述如下:

类A、B有公有和私有类型、成员函数、成员数据,类C有些公有函数,怎样让类C的共有函数能随时访问类A、类B的所有成员?

问题具体说明如下:

class Class1 {

public:
    int num_tokens;
    typedef vector<int> int_1vec;

    Class1() {
        cout << "class1 constructor!" << endl;
    }

private:
    int config;

};

class Class2 {

public:
    int frame;
    
    Class2() {
        cout << "class2 constructor!" << endl;
    }
    
private:
    int cur_cost;
    int next_cost;
    typedef vector<string> string_1vec;
    
};

class Class3 {

public:
    void* run(void*);

private:
    int beam;

}

怎样让类Class3的run函数能访问到Class1、Class2的所有成员,包括Class1的公有成员num_tokens、共有类型int_1vec,Class2的公有成员frame、私有类型string_1vec?

以下贴出两种方法来解决这个问题:

方法1: 将Class3声明为Class1和Class2的组合,也就是利用C++中的“组合机制”。

头文件代码如下:

#ifndef MULTI_CLASS_H
#define	MULTI_CLASS_H

#include <vector>
#include <string>
#include <iostream>

using namespace std;

class Class3; // 必须先声明!

class Class1 {   
    // 声明为友元类,这样就可以直接在Class3中使用Class1的私有类型了
    // 如果没有此声明,则只能访问Class1的公有部分  
    friend class Class3;
public:
    int num_tokens;
    typedef vector<int> int_1vec;

    Class1() {
        cout << "class1 constructor!" << endl;
    }

private:
    int config;

};

class Class2 {
    friend class Class3;  // 同上
public:
    int frame;

    Class2() {
        cout << "class2 constructor!" << endl;
    }

private:
    int cur_cost;
    int next_cost;
    typedef vector<string> string_1vec;

};

class Class3 {

public:
    Class3() {
        cout << "class3 constructor!" << endl;
    }

    void print();

private:
    Class1 obj1;
    Class2 obj2;

};

#endif	/* MULTI_CLASS_H */

源文件定义如下:

#include "multi-class.h"

void Class3::print() {
    cout << "obj1 beam is: " << obj1.num_tokens << endl;
    Class1::int_1vec int_vec; // 使用Class1的公有类型
    for (int i = 0; i < 10; ++i)
        int_vec.push_back(i);
    for (int i = 0; i < 10; ++i)
        cout << int_vec[i] << " ";
    cout << endl;

    Class2::string_1vec string_vec; // 使用Class2的私有类型
    for (int i=0; i<10; ++i) {
        string tmp = "hello";
        string_vec.push_back(tmp);
    }
    for (int i=0; i<10; ++i)
        cout << string_vec[i] << " ";
    cout << endl;

};

主函数的简单测试如下:

#include <cstdlib>
#include "multi-class.h"

using namespace std;

int main(int argc, char** argv) {

    Class3 class3;
    class3.print();
    return 0;
}

输出结果如下:

class1 constructor!
class2 constructor!
class3 constructor!
obj1 beam is: 0
0 1 2 3 4 5 6 7 8 9
hello hello hello hello hello

从结果也能看到“组合”类中构造函数的调用顺序。

方法2:Class3同时继承基类Class1和基类Class2,也即C++中的“多继承”机制。

头文件如下:

#ifndef MULTI_CLASS_H
#define	MULTI_CLASS_H

#include <vector>
#include <string>
#include <iostream>

using namespace std;

class Class3; // 此处同样需要友元声明

class Class1 {
    friend class Class3;

public:
    int num_tokens;
    typedef vector<int> int_1vec;

    Class1() {
        cout << "class1 constructor!" << endl;
    }

private:
    int config;

};

class Class2 {
    friend class Class3;

public:
    int frame;

    Class2() {
        cout << "class2 constructor!" << endl;
    }

private:
    int cur_cost;
    int next_cost;
    typedef vector<string> string_1vec;

};

class Class3: public Class1, public Class2 { // 多继承的写法

public:
    Class3() {
        cout << "class3 constructor!" << endl;
    }

    void print();

private:  

    int i;

};

#endif	/* MULTI_CLASS_H */

源文件定义如下:

#include "multi-class.h"

void Class3::print() {
    cout << "obj1 beam is: " << num_tokens << endl; // 注意这里就是num_tokens!
    int_1vec int_vec; // 对Class1公有成员的直接继承,不需要 Class1:: 域作用符
    for (int i = 0; i < 10; ++i)
        int_vec.push_back(i);
    for (int i = 0; i < 5; ++i)
        cout << int_vec[i] << " ";
    cout << endl;

    string_1vec string_vec; // 对Class2私有类型的直接继承
    for (int i=0; i<5; ++i) {
        string tmp = "hello";
        string_vec.push_back(tmp);
    }
    for (int i=0; i<5; ++i)
        cout << string_vec[i] << " ";
    cout << endl;

};

主函数的调用和方法1的一致,结果也与方法1一致,略。

关于C++中‘‘友元"的简单介绍,可参见博客:

http://www.cnblogs.com/BeyondAnyTime/archive/2012/06/04/2535305.html

时间: 2024-10-21 15:35:12

C++ 友元、组合、继承的简单使用的相关文章

[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表

所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的 把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势 比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡 鸡腿堡+鸡翅+紫薯

Javascript之对象组合继承

感悟: 最近看了一些关于Javascript对象继承的知识,发现自己之前虽然看了一些书,但是很多知识都忘了.虽然很多东西都忘了,但再次看的过程中对这些东西不会再向刚接触时那么陌生,而且理解起来也比之前顺畅和透彻多了. 充分说明:多看书是有意义的. ————————————————————————————————————————————————————————————————————————————————————————————碎碎念 关于对象之间的继承,在Javascript中主要是通过原型对

[js高手之路]从原型链开始图解继承到组合继承的产生

于javascript原型链的层层递进查找规则,以及原型对象(prototype)的共享特性,实现继承是非常简单的事情 一.把父类的实例对象赋给子类的原型对象(prototype),可以实现继承 1 function Person(){ 2 this.userName = 'ghostwu'; 3 } 4 Person.prototype.showUserName = function(){ 5 return this.userName; 6 } 7 function Teacher (){}

JS继承之借用构造函数继承和组合继承

根据少一点套路,多一点真诚这个原则,继续学习. 借用构造函数继承 在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术(有时候也叫做伪造对象或经典继承).这种技术的基本思想相当简单,即在子类型构造函数的内部调用超类型构造函数. 基本模式 function SuperType(){ this.colors = ["red", "blue", "green"]; } fu

JavaScript ----------- 组合继承

继承 实现继承:继承实际的方法.ECMAScript 只支持实现继承,而且其实现基础主要是依靠原型链来实现的. 基本思想是:利用原型来实现一个引用类型继承另外一个引用类型的属性和方法. 原型 - 构造函数 - 实例 之间的关系 构造函数(prototype) <-------> 原型(constructor) <------- 实例(_proto_) 实现原型链有一种基本模式,其代码大致如下 1 function SuperType(){ 2 3 this.property = true

JS继承(简单理解版)

童鞋们,我们今天聊聊js的继承,关于继承,平时开发基本用不到,但是面试没有不考的,我就想问,这是人干的事吗? 好吧,迫于社会主义核心价值观,我们今天就来简单说一说js的继承,谁让它是面向对象编程很重要的一个方面呢 首先一句定义,什么是继承: A对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法. 常见的集成方式有六种,我们今天依次简单的说一下,现在让我们把这六种方式分一下类,大致上可分为三类 第一类:普通类 这类继承方法有个特性,就是简单,容易实现,一共两种: 1.原型链继承 关键点

寄生组合继承

寄生组合式继承,是集寄生式继承和组合继承的有点与一身,主要是通过借用构造函数来继承属性,通过原型链的混成形式来继承方法. 先看一个例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function inheritPrototype(SuperType, SubType){     var prototype = Object.create(SuperType.prototype);     prototype.constructor = SubType;     SubT

组合继承和寄生组合继承的区别

组合继承 核心思想:使用借用构造函数的技术实现实例属性的继承,使用原型链实现原型属性和方法的继承. function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age

JS 面向对象之继承--多种组合继承

转自 http://www.cnblogs.com/yangjinjin/archive/2013/02/01/2889563.html 这一次要讲 组合.原型式.寄生式.寄生组合式继承方式. 1. 组合继承:又叫伪经典继承,是指将原型链和借用构造函数技术组合在一块的一种继承方式. 下面来看一个例子: function SuperType(name) { this.name = name; this.colors = ["red", "blue", "gr

利用友元+虚继承实现不可被继承的类

这个问题的传统解法是把构造和析构函数设为private,但是有很多不方便的地方,如无法直接定义它的对象. 一个非常开脑洞的做法是使用友元+虚继承来实现. template<typename T> class A { friend T; private: A() {}; ~ A() {}; }; class B: virtual public A<B> { }; class C :public B { }; int main() { C c; return 0; } 定义类模版A为不