程序员C++

friend友元类的一种用法

2016-01-14  本文已影响92人  littlersmall

本意是要设计一个存储表的内存结构,可是要求又比较奇特:既能提供类似vector的调用方式,又能有map的特性。于是自己设计了一个怪模怪样的类:

class Table
 {   
     std::vector<std::vector<std::string> > talbe_;
     public:
     Table();
     int find(const int index, const char* value);
     std::vector<std::string>& operator[](const int index);
    
      int size();
      int column_num();
}; 

但是这样使用时,主类的调用接口如果传递的是引用,比如下面这样:

int get_table(const char* table_name, Table& table);

这里虽然传递了引用,仍然涉及一些内存拷贝的事情,而且构造一个这样的对象,开销本是不必要的,而如果使用一个指针的引用,比如:

int get_table(const char* table_name, Table*& table);

这样使用时会出现 (*table)[index]这样怪异的写法。

后来总算想到一种办法,将class Table中的 table_换为一个index,而Table由于要调用一些主类中的数据,因此将Table声明为主类的friend。
大致是这样的:

class Table
{   
    int index_;
    public:
    Table();
    int find(const int index, const char* value);
    std::vector<std::string>& operator[](const int index);
    
    int size();
    int column_num();
};  
        
class ConfManager
{   
    friend class Table;
    std::vector<std::string> conf_file_array_;
    std::vector<std::string> so_file_array_;
    std::vector<std::vector<std::vector<std::string> > > table_array_;
};

本来以为是万事大吉,可是主类中要设置Table时,又需要访问Table::index_,提供一个set方法又不好,因此,只能再把主类作为Table的friend。这样以来,又混乱不堪了。
最后灵光一闪,将Table作为主类的一个内部类,同时,将主类作为Table的friend类,这样大家都可以访问私有成员,而对于用户却又是透明的。如下:

class ConfManager
{   
    std::vector<std::string> conf_file_array_;
    std::vector<std::string> so_file_array_;
    std::vector<std::vector<std::vector<std::string> > > table_array_;
    std::vector<std::string> table_name_array_;
    public:
    class Table
    {   
        friend class ConfManager;
        int index_;
        public:
        Table();
        int find(const int index, const char* value);
        std::vector<std::string>& operator[](const int index);
    
        int size();
        int column_num();
     };  
      
     static ConfManager& get_conf_manager();                                                  
};

确实有一种浑然天成的味道,为了外面使用方便,再加个typedef,如下:

typedef ConfManager::Table Table;

friend关键字,在effective c++中被诟病再三,主要原因是它破坏了程序的封装性。不过万事万物都有它存在的必要性,话说回来,依赖于class,private,protected,等等所维护的封装性,都只存在于编译期而已。真正让人头疼的,还是运行起来的各种越界和泄漏。
原文时间(2014-3-13)

上一篇 下一篇

猜你喜欢

热点阅读