2016-07-22 17 views
0

Привет, ребята в моей C++ программы У меня есть четыре класса (A, B, C, D)Шаблон массива указателей C++?

  • А базовый класс
  • B наследует от A
  • C наследует от A
  • D наследуется от B

Все они являются шаблонные классы template<class Type> и каждый из них имеет метод печати, который печатает свои закрытые члены и частные члены класса, которые он наследует от.

Так что B будет печатать B частных членов и частных членов, C будет печатать C частных членов и частных членов, D будет печатать своих частных членов и B, частных членов.

В основной функции я хочу создать массив указателей для класса A, которые имеют 3 местоположения для объекта каждого класса, тогда я хочу, чтобы цикл каждого метода печати объекта.

проблема заключается в том, что я меняю классы на классы шаблонов. Я получил сообщение об ошибке: «что у моих классов нет конструкторов»; однако у них есть их.

вот мой код Пожалуйста, помогите (Обратите внимание, я заметил, где ошибка происходит для вас):

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

template <class Type> 
class A 
{ 
public: 
virtual void print() 
{ 
    cout<<"the base class (A) private (x) is : "<<x<<endl; 
} 

A(Type X = 0) 
{ 
    x = X; 
} 
void setX(Type X) 
{ 
    x = X; 
} 

Type getX() const 
{ 
    return x; 
} 

private: 
Type x; 
}; 


template <class Type> 
class B:public A 
{ 
public: 
B(Type X = 0,Type Y = 0) 
{ 
    setX(X); 
    y = Y; 
} 
void setY(Type Y) 
{ 
    y = Y; 
} 

Type getY() const 
{ 
    return y; 
} 

void print() 
{ 
    A::print(); 

    cout<<"private (y) in class (B) is : "<<getY()<<endl; 
} 

private: 
Type y; 
}; 

template <class Type> 
class C:public A 
{ 
public: 
C(Type X = 0,Type Z = 0) 
{ 
    setX(X); 
    z = Z; 
} 
void setZ(Type Z) 
{ 
    z = Z; 
} 

Type getZ() const 
{ 
    return z; 
} 

void print() 
{ 
    A::print(); 

    cout<<"private (z) in class (C) is : "<<getZ()<<endl<<endl; 
} 

private: 
Type z; 
}; 


template <class Type> 
class D:public B 
{ 
public: 
D(Type X = 0,Type Y = 0,Type W = 0) 
{ 
    setX(X); 
    setY(Y); 
    w = W; 
} 
void setW(Type W) 
{ 
    w = W; 
} 

Type getW() const 
{ 
    return w; 
} 

void print() 
{ 
    B::print(); 

    cout<<"private (w) in class (D) is : "<<getW()<<endl; 
} 

private: 
Type w; 
}; 


void main() 
{ 
A<int>* arrayOfPointers[3]; 

arrayOfPointers[0] = new B(1,100);//error here 
arrayOfPointers[1] = new C(2,200);//error here 
arrayOfPointers[2] = new D(3,300,3000);//error here 

for(int i = 0 ; i<3;i++) 
{ 
    cout<<typeid(*arrayOfPointers[i]).name()<<" Print method : \n"<<endl; 
    arrayOfPointers[i]->print(); 
    cout<<"**********************\n"<<endl; 
} 

} 
+1

При публикации на SO попытайтесь найти наименьший пример, который все еще отображает ошибку, и предоставить точное сообщение об ошибке. Вам, вероятно, нужен только A & B для получения ошибки здесь, поэтому вы можете сократить свой код наполовину. –

+2

В классе B: public A', что 'A' вы наследуете? Поскольку 'A' является шаблоном, его имя недостаточно. – NathanOliver

+2

Я думаю, что «все из них являются шаблонами», является симптомом недоразумения, в котором вы находитесь. Это классные шаблоны. Это означает, что если у вас есть 'template class A', то' A' не является классом.Только после того, как вы укажете все параметры шаблона, он станет фактическим классом. Итак, 'A ' например, будет классом. – PeterT

ответ

1

Вы забыли две вещи:

1) Ваше наследство нужно указать аргументы шаблона для класса они наследуемых от. Например:

template <class Type> 
class B : public A<Type> 
{ 
    ... 
} 

2) Когда вы инстанцирование классов, вам необходимо предоставить аргументы шаблона, тоже:

arrayOfPointers[0] = new B<int>(1, 100); 
arrayOfPointers[1] = new C<int>(2, 200); 
arrayOfPointers[2] = new D<int>(3, 300, 3000); 

Однако, вы можете также предоставить функции шаблонов для создания экземпляров этих классов от прилагаемого аргументы, как те делают _ (...) методы из станд библиотеки:

template <class Type> 
B<Type>* create_B(const Type& t1, const Type& t2) 
{ 
    return new B<Type>(t1, t2); 
} 

и использовать его как это:

arrayOfPointers[0] = create_B(1, 100); 

Однако имейте в виду, что эти методы создают необработанные указатели на выделенную кучную память, поэтому вы несете ответственность за ее удаление (вы можете использовать shared_ptrs или что-то другое, чтобы преодолеть это или просто вернуть объект и т. Д., Но на самом деле это не часть вашего вопроса/моего ответа).

0

Вы наследоваться от A, но вы должны наследовать от конкретного экземпляра A<T>. Может быть class B:public A<Type>?

+1

как и для 1) 'A (Type X = 0)' является допустимым заменителем конструктора по умолчанию. А что касается 3) он уже имеет массив указателей – PeterT

+0

Вправо, удалил первый (и я уже заметил и удалил третий) – Dutow

Смежные вопросы