2013-04-13 2 views
1

Мне нужно создать конструктор, который возьмет два целых числа в качестве аргументов.

Оттуда мне нужно вызвать метод, беря эти целые числа по ссылке. Внутри этого метода я должен динамически преобразовывать целые числа в тип char* (массив цифр).

В конце конструктора у меня должно быть два массива char* вместо начальных целых чисел.Шаблонные классы - пара вопросов

Я вроде как должен сделать это так, потому что другой класс делает то же самое, что и на структурах. И сохраните их в атрибутах шаблона.


Я новичок в языке C++, но первым условием было использование шаблонов. Я сделал небольшое исследование по этой теме и выяснил, что он должен работать.

Я хотел бы скомпилировать все это сам, но беспорядок с внедрением классов C++ в моей голове создает довольно длинный список ошибок компиляции.


Первый вопрос - это можно сделать, используя шаблоны? Второй вопрос, потому что я уже написал что-то на себе:

template <class type> class Addition { 
    type num_a; 
    type num_b; 
    void convert(type, type); 
public: 
    Addition(type, type); 
} 

template <class type> Addition::Addition(type a, type b) { 
    convert(&a, &b); 
    num_a = a; 
    num_b = b; 
} 
template <class type> Addition::convert(type *a, type *b) { 
    int temp_a = a, temp_b = b; 
    a = char[256], b = char[256]; 
    // converting 
} 

Является ли это Годится, или я сделал что-то не так?
Есть ли у вас какие-либо предложения о том, как я реализую классы в C++?

Почему я не могу инициализировать атрибут со значением, например:

template <class type> class Addition { 
    type outcome = 0; 
} 

И если нет необходимости использовать это ключевое слово в C++, как я делаю что-то вроде этого ?:

template <class type> Addition::Foo(type a, type b) { 
    this->a = a; // a = a; 
    this->b = b; // b = b; 
} 
+0

Не похоже, что здесь нужны шаблоны. Отбросьте их сначала, затем решите оставшиеся проблемы. –

ответ

2

Отказ от ответственности: Я не могу судить, что вам действительно нужны шаблоны для того, что вы делаете. Это будет зависеть от количества различных типов, с которыми вы хотите работать с шаблоном класса дополнений. Если вы будете использовать его только для int, то, возможно, это приведет к излишней сложности. Вы всегда можете реорганизовать позже (это будет подход Agile).

Сказав, что, если вы хотите использовать шаблоны, обычная условность, чтобы написать T для параметра шаблона, а также использовать type для вложенного typedef внутри шаблона класса. Использование typename или class является вопросом вкуса, но typename подчеркивает тот факт, что встроенные типы также могут передаваться в качестве аргументов. Однако следует отметить, что с параметрами шаблона шаблона вам нужно будет написать

template<template<typename> class U> SomeClass { /* your definition */ }; 
          ^^^^^ // <-- NOT typename here 

, который подчеркивает тот факт, что только шаблоны классов могут быть переданы в качестве аргументов.

Есть несколько других nitpicks, которые можно было бы упомянуть о вашем коде, которые сделали бы его не компилировать (отсутствует тип возвращаемого значения в convert() и отсутствие запятой в определении класса):

template <typename T> 
class Addition 
{ 
    static const std::size_t N = 256; // are you sure that 256 is all you'll ever need? 
    T num_a; 
    T num_b; 
    void convert(T const*, T const*); // by T const*, not T* 
public: 
    Addition(T const&, T const&); // by T const&, not T 
}; // <-- make sure to end class definitions with a semi-colon! 

template <typename T> 
Addition::Addition(T const& a, T const& b) 
{ 
    convert(&a, &b); 
    num_a = a; 
    num_b = b; 
} 

template <typename T> 
void Addition::convert(T const* a, T const* b) // <-- use T const* if you don't modify the parameters 
^^^^ // <-- you forgot the return type 
{ 
    int temp_a = a, temp_b = b; 
    a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only 
    // converting 
} 

В C + +11 вы можете даже использовать Делегирование конструкторов (поддерживается последним Visual C++ и конечно GCC/Clang) и написать

template <typename T> 
Addition::Addition(T const& a, T const& b) 
: 
    Addition(&a, &b) // delegate to the other constructor 
{} 

template <typename T> 
Addition::Addition(T const* a, T const* b) // <-- use T const* if you don't modify the parameters 
{ 
    int temp_a = a, temp_b = b; 
    a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only 
    // converting 
} 

Наконец, поскольку определение шаблона должно быть в заголовках YWAY, вы могли бы даже написать все внутри определения класса, как это:

template <typename T> 
class Addition 
{ 
    static const std::size_t N = 256; // are you sure that 256 is all you'll ever need? 
    T num_a; 
    T num_b; 

    Addition(T const*, T const*) // by T const*, not T* 
    { 
     int temp_a = a, temp_b = b; 
     a = char[N], b = char[N]; 
     // converting 
    } 
public: 
    Addition(T const&, T const&) // by T const&, not T 
    : 
     Addition(&a, &b) // delegate to the other constructor 
    {} 
}; // <-- make sure to end class definitions with a semi-colon! 

Это спасает вас от утомительного написания обеих деклараций и определения всех функций-членов. Для коротких и сладких классов (к чему вы должны стремиться в любом случае) это предпочтительный способ написания шаблонов, но для очень длинных определений вы можете отделить декларацию и определение.

Наконец, как объяснялось @tacp, вам действительно нужно использовать this->a для устранения неоднозначности элемента данных класса из параметра функции. По этой причине люди часто пишут элементы данных с завершающим подчеркиванием или префиксом m_.

1

для ваших последних вопросов:

template <class type> class Addition { 
    //type outcome = 0; 
    //^^^^you have to call default constructor of type 
    type outcome = type(); 
} 

лучше использовать typename для конвенции, используя class также ОК.

template <class type> Addition::Foo(type a, type b) { 
    this->a = a; // a = a; 
    this->b = b; // b = b; 
} 

Если передаваемый параметр и член имеет то же имя, что вам нужно использовать this. Вы не можете сделать

a =a; 
b =b; 

a,b, поскольку в локальной области, но this->a означает класс члена a.

Поскольку вы всегда хотите преобразовать целые числа в char array, я не думаю, что вам действительно нужны шаблоны. Если вы не хотите конвертировать double, float и другие типы в char* также в будущем. Я не рассматривал все проблемы, поэтому могут остаться другие.

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