2015-05-02 2 views
0

Можно ли добиться чего-то подобного? Вместо того, чтобы иметь разные функции, которые создают экземпляры разных классов, было бы неплохо, если бы можно было написать одну единственную функцию, которая могла бы создавать разные классы, если они получены из базового класса и принимают те же аргументы.C++ экземпляр класса через шаблон

#include <iostream> 
#include <string> 
#include <vector> 
#include <limits> 

class Base 
{ 
    void DoSomething() 
    { 
     std::cout << "Oh yes" << std::endl; 
    } 
}; 

class Derived1 : public Base 
{ 

}; 

class Derived2 : public Base 
{ 

}; 

template <typename T> 
T* Create<T>() 
{ 
    return new T; 
} 

int main() 
{ 
    auto* test = Create<Derived1>(); 
    test->DoSomething(); 
    delete test; 

    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); 
    return 0; 
} 
+0

Это должно работать. В чем дело? –

+0

Исправьте свой синтаксис как 'template T * Create()' –

+1

И сделайте свой 'Base :: DoSomething'' public' – vsoftco

ответ

2

Ваш

void DoSomething() 

функция член класса private по умолчанию, как это было сказано с vsoftco's comment. При этом public может исправить ваши основные (синтаксические) проблемы.


С семантической точки зрения:

Не используйте new/new[], delete/delete[] и сырые указатели/массивы C-стиль непосредственно пожалуйста! Если вы действительно не знаете, что вам это нужно, и вам нужен контроль низкого уровня, это будет осложнять ваш код без необходимости.

Для такого рода Factory pattern, я бы рекомендовал использовать смарт-указатели с C++ стандартных объектов управления динамической памяти:

template <typename T> 
std::unique_ptr<T> Create() { 
    return std::unique_ptr<T>(new T()); 
    // Alternatively for c++14 
    // return std::make_unique<T>(); 
} 

Значение выше является most simple variant, где фабричный метод просто раздает право собственности на вызывающий абонент.

Настоящая фабрика может позаботиться о подключении большего количества наблюдателей или других вещей к созданному экземпляру, и вам в конечном итоге понадобится идиома .


Есть более жесткий взгляд на ваш код, как следующим образом:

template <typename T> 
T* Create() { 
    return new T; 
} 

int foo() { 
    auto* test = Create<Derived1>(); 
    test->DoSomething(); 
    delete test; // what actually happens if Create<Derived1>() or 
       // test->DoSomething(); throws an exception? 
       // Is the allocated memory tidied up? 

    // Irrelevant: 
    // std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); 
    return 0; 
} 

int main() { 
    int retcode = foo(); // Slightly deviated your sample 
    // do something else ... 
    return retcode; 
} 
+0

ofc, я просто играл с заводской функцией и напортачил, поставив рядом с именем функции = синтаксическая ошибка. –

+0

@nilo Добавил некоторые ссылки, вы можете прочитать их. –

+1

Почему «Создать ' '' '' '' '' '' '' '' '' '' '' '' '' '' – Lingxi

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