Dziedziczenie z klasy szablonu w c++

Załóżmy, że mamy klasę szablonów Area, która ma zmienną member T area, A T getArea() i void setArea(T) Funkcje member.

Mogę utworzyć Area obiekt określonego typu wpisując Area<int>.

Teraz mam klasę Rectangle, która dziedziczy klasę Area. Ponieważ Rectangle nie jest szablonem, nie mogę wpisać Rectangle<int>.

Jak wyspecjalizować dziedziczony typ Area dla Rectangle obiektów?

EDIT: Przepraszam, zapomniałem wyjaśnić - moje pytania brzmią, czy jest możliwe Dziedzicz obszar bez specjalizowania go, więc nie jest dziedziczony jako obszar ints, ale jako obszar prostokąt może specjalizować typy dla.

Author: dtech, 2012-01-11

6 answers

Dla zrozumienia szablonów, bardzo korzystne jest uporządkowanie terminologii, ponieważ sposób, w jaki o nich mówisz, decyduje o sposobie myślenia o nich.

W szczególności, Area nie jest klasą szablonową, ale szablonem klasowym. Oznacza to, że jest to szablon, z którego można generować klasy. Area<int> jest taką klasą (jest to a nie obiekt, ale oczywiście można utworzyć obiekt z tej klasy w taki sam sposób, jak można tworzyć obiekty z każdej innej klasy). Kolejny taki Klasa to Area<char>. Zauważ, że są to zupełnie różne klasy, które nie mają nic wspólnego z wyjątkiem faktu, że zostały wygenerowane z tego samego szablonu klasy.

Ponieważ Area nie jest klasą, nie można wyprowadzić z niej klasy Rectangle. Możesz tylko wyprowadzić klasę z innej klasy (lub kilku z nich). Ponieważ Area<int> jest klasą, można na przykład wyprowadzić Rectangle z niej:

class Rectangle:
  public Area<int>
{
  // ...
};

Ponieważ Area<int> i Area<char> są różnymi klasami, można nawet czerpać z obu w w tym samym czasie (jednak przy dostępie do ich członków będziesz musiał poradzić sobie z niejednoznacznością): {]}

class Rectangle:
  public Area<int>,
  public Area<char>
{
  // ...
};

Musisz jednak określić, z której klasy wywodzić się, gdy zdefiniujesz Rectangle. Jest to prawdą bez względu na to, czy te klasy są generowane z szablonu, czy nie. Dwa obiekty tej samej klasy po prostu nie mogą mieć różnych hierarchii dziedziczenia.

Możesz zrobić Rectangle również szablon. Jeśli napiszesz

template<typename T> class Rectangle:
  public Area<T>
{
  // ...
};

Masz szablon Rectangle z którego możesz otrzymać klasę Rectangle<int>, która wywodzi się z Area<int>, oraz inną klasę Rectangle<char>, która wywodzi się z Area<char>.

Może być tak, że chcesz mieć jeden typ Rectangle, aby można było przekazać wszystkie rodzaje Rectangle do tej samej funkcji (która sama nie musi znać typu obszaru). Ponieważ klasy Rectangle<T> generowane przez utworzenie instancji szablonu Rectangle są formalnie niezależne od siebie, nie działa to w ten sposób. Można jednak korzystać z wielu dziedziczeń tutaj:

class Rectangle // not inheriting from any Area type
{
  // Area independent interface
};

template<typename T> class SpecificRectangle:
  public Rectangle,
  public Area<T>
{
  // Area dependent stuff
};

void foo(Rectangle&); // A function which works with generic rectangles

int main()
{
  SpecificRectangle<int> intrect;
  foo(intrect);

  SpecificRectangle<char> charrect;
  foo(charrect);
}

Jeśli ważne jest, aby rodzajnik Rectangle pochodzi od generyka Area, możesz zrobić tę samą sztuczkę z Area również:

class Area
{
  // generic Area interface
};

class Rectangle:
  public virtual Area // virtual because of "diamond inheritance"
{
  // generic rectangle interface
};

template<typename T> class SpecificArea:
  public virtual Area
{
  // specific implementation of Area for type T
};

template<typename T> class SpecificRectangle:
  public Rectangle, // maybe this should be virtual as well, in case the hierarchy is extended later
  public SpecificArea<T> // no virtual inheritance needed here
{
  // specific implementation of Rectangle for type T
};
 167
Author: celtschk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 21:16:49

Czy ty po prostu próbujesz czerpać z Area<int>? W takim przypadku robisz to:

class Rectangle : public Area<int>
{
    // ...
};

EDIT: po wyjaśnieniu, wydaje się, że próbujesz zrobić Rectangle również szablon, w którym to przypadku powinno działać:

template <typename T>
class Rectangle : public Area<T>
{
    // ...
};
 13
Author: Stuart Golodetz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 22:43:40
class Rectangle : public Area<int> {
};
 8
Author: ldanko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 20:46:27

Rectangle będzie musiał być szablonem, w przeciwnym razie jest to tylko jeden typ . Nie może być nie-szablonem, podczas gdy jego baza magicznie jest. (Jego bazą może być szablon instancja, choć wydaje się, że chcesz zachować funkcjonalność bazy jako szablon.)

 6
Author: Lightness Races in Orbit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 20:44:24

Uczyń prostokąt szablonem i przekaż nazwę typową do obszaru:

template <typename T>
class Rectangle : public Area<T>
{

};
 6
Author: pezcode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 22:44:13
#include<iostream>

using namespace std;

template<class t> 
class base {
protected:
    t a;
public:
    base(t aa){
        a = aa;
        cout<<"base "<<a<<endl;
    }
};

template <class t> 
class derived: public base<t>{
    public:
        derived(t a): base<t>(a) {
        }
        //Here is the method in derived class 
    void sampleMethod() {
        cout<<"In sample Method"<<endl;
    }
};

int main() {
    derived<int> q(1);
    // calling the methods
    q.sampleMethod();
}
 0
Author: Narendra kumawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 17:32:21