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?

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

方法1: 仅将Class3声明为Class1和Class2的友元类,这样就可以让Class3的成员函数访问到Class1和Class2的所有成员了,具体代码如下,

头文件代码如下:

#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:
    static 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;
    
};

struct struct1 {
    static int ss;
};


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

    void print(Class1&); // 传入参数,方便访问Class1的非static数据成员
    
private:  
    
    int i;
    
};


#endif	/* MULTI_CLASS_H */
源文件定义如下:

#include "multi-class.h"

int Class1::num_tokens = 1; // 静态非const成员的定义,必须在类外定义,而且只能定义一次,所以放在这里定义比较合适

void Class3::print(Class1& obj) {
    cout << "obj1 beam is: " << Class1::num_tokens << endl; //  对static成员的访问
    cout << "obj1 config is: " << obj.config << endl; // 对非static成员的访问
    Class1::int_1vec int_vec; // 对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;
    
    Class2::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;
    
        
};
主程序如下:

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

using namespace std;

int main(int argc, char** argv) {
    
    Class3 class3; Class1 c; // 对非static成员的访问,必须传入对象
    class3.print(c);
    return 0;
}
测试结果如下:

class3 constructor!
obj1 beam is: 1
obj1 config is: 0
0 1 2 3 4 
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 {    
    // 声明为友元类,这样就可以直接在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
从结果也能看到“组合”类中构造函数的调用顺序。

方法3: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:
 // 类设计者定义了自己的构造函数后,编译器就不会再生成默认构造函数了
 // 必须保证在自动调用Class1和Class2的构造函数时有特定匹配的构造函数可以用
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值