общедоступные шаблоны классов друзей - PullRequest
1 голос
/ 17 ноября 2011

Если у меня есть иерархия такого типа:

#include <iostream>

using namespace std;

template<class T>
class typeB;

template<class T>
class typeA 
{
    // Private data
        T* x_;
        int size_;
    public:
        // Constructors
        typeA()
            : x_(0), size_(0)
        {
        };
        typeA(int size)
            : x_(0), size_(size)
        {
        }

        // Friend classes.
        friend class typeB<T>;
};

template<class T>
class typeB
: public typeA<T>  
{
    public:
        // Constructors
        typeB ()
        {
        };
        typeB (int size)
            : typeA<T>(size)
        {
            //this->x_ = new T[size];
            x_ = new T[size];
        }
};

int main()
{
    typeB<int> b(4);

    return 0;
}

, почему мне нужно указать "this-> x_ = new T [size]" в конструкторе typeB (int size) вместо "x_= новый T [размер] ", чтобы получить этот код для компиляции?

Что мне говорит компилятор, так это то, что он не может разрешить тип x _:

main.cpp: In constructor ‘typeB<T>::typeB(int)’:
main.cpp:42: error: ‘x_’ was not declared in this scope

Если typeB является другом типа A, он должен иметь открытый доступ к атрибутам typeA.Если я попробую это с не шаблонными классами, это сработает:

#include <iostream>

using namespace std;

class typeB;

class typeA 
{
    // Private data
        int* x_;
        int size_;
    public:
        // Constructors
        typeA()
            : x_(0), size_(0)
        {
        };
        typeA(int size)
            : x_(0), size_(size)
        {
        }

        // Friend classes.
        friend class typeB;
};

class typeB
: public typeA
{
    public:
        // Constructors
        typeB ()
        {
        };
        typeB (int size)
            : typeA(size)
        {
            x_ = new int[size];
        }
};

int main()
{
    typeB b(4);

    return 0;
}

typeA и typeB являются своего рода контейнерами списка: как вы думаете, что будет мотивом для такого рода отношений (публичное наследование + друзьяvs наличие x_ и size_ в качестве защищенных атрибутов, если требуется прямой доступ)?

1 Ответ

3 голосов
/ 17 ноября 2011

Прежде всего, член x_ является частным членом базового класса.Здесь дружба не поможет, поскольку вы пытаетесь получить доступ к членам через наследование.

Даже если вы сделаете его защищенным или общедоступным, члены базового класса шаблона не будут автоматическивидимый в производном классе.

Решение:

  1. Используйте this-> явно как,

     this->x_ = new int[size];
    
  2. Или приведите имена в область производного класса как:

     template<class T>
     class typeB : public typeA<T>  
     {
             using typeA<T>::x_; //brings the name x_ into the class scope!
             //...
    

    , тогда вы можете написать

     x_ = new int[size];
    
...