Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
viktorius
2 / 2 / 2
Регистрация: 24.02.2013
Сообщений: 105
#1

Вызов конструктора шаблонного класса - C++

28.12.2013, 05:45. Просмотров 1081. Ответов 11
Метки нет (Все метки)

Есть шаблонный класс стек, он является полем в классе Express, но компилятор выдает ошибку
" Ошибка 1 error C2614: Express: недопустимая инициализация члена: 'Stack' не является базовым классом или членом"


C++
1
2
3
4
5
6
7
8
9
class Express
{
    Stack <char> s;
    char *str;
    int len;
public:
    Express();
    Express(const char *);
};
C++
1
2
3
4
5
6
7
8
9
Express::Express(): Stack(), str(0), len(0)//здесь ошибка 
{}
 
Express::Express(const char *ss): Stack()//и здесь
{
    len = strlen(ss);
    str = new char[len + 1];
    strcpy(str, ss);
}
Объясните как правильно вызывать конструктор шаблонного класса стек в классе Express
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.12.2013, 05:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Вызов конструктора шаблонного класса (C++):

Неявный вызов конструктора шаблонного класса при операции сравнения - C++
Реализовал шаблонный класс целых чисел, для использования его в шаблонном классе дробей. Звучит жутковасто. :D Так вот, в классе целых...

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

Различное поведение конструктора шаблонного класса в зависимости от типа параметра - C++
Здравствуйте. Возникла проблема - при попытке изменить поведение конструктора шаблонного класса (структуры) в зависимости от типа...

Как корректно передать в метод шаблонного класса объект шаблонного класса в качестве параметра? - C++
header.h template &lt;class T&gt; class MyVector { public: void swap(MyVector&lt;T&gt;Vector); } template &lt;class T&gt; void...

Вызов конструктора базового класса из класса-наследника - C++
Можно ли вне списка инициализации вызвать конструктор базового класса ? class A { int a; public: A(int c):a(c){} ...

Вызов конструктора класса - C++
есть класс Set, и в нем есть конструктор, как с этого конструктора мне массивы перенести в метод другого класса так что бы над ними можно...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.12.2013, 05:59 #2
Цитата Сообщение от viktorius Посмотреть сообщение
Объясните как правильно вызывать конструктор шаблонного класса стек в классе Express
И зачем его, в данном случае, вызывать? Конструктор по умолчанию и так вызовется.
viktorius
2 / 2 / 2
Регистрация: 24.02.2013
Сообщений: 105
28.12.2013, 06:11  [ТС] #3
Цитата Сообщение от alsav22 Посмотреть сообщение
И зачем его, в данном случае, вызывать? Конструктор по умолчанию и так вызовется.
чтоб создать объект шаблонного класса

если я убираю Stack()

C++
1
2
3
4
5
6
7
8
9
Express::Express(): str(0), len(0)
{}
 
Express::Express(const char *ss)
{
    len = strlen(ss);
    str = new char[len + 1];
    strcpy(str, ss);
}
выдает ошибки Ошибка 2 error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall Stack<char>::Stack<char>(void)" (??0?$Stack@D@@QAE@XZ) в функции "public: __thiscall Express::Express(void)" (??0Express@@QAE@XZ) express.obj
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.12.2013, 06:19 #4
Цитата Сообщение от viktorius Посмотреть сообщение
чтоб создать объект шаблонного класса
Конструкторы не создают объекты, они инициализируют поля. Объект Stack <char> s будет создан при создании объекта Express и инициализированн (в данном случае) конструктором по умолчанию.

Добавлено через 2 минуты
Но если очень хочется явно инициализировать:
C++
1
2
3
4
5
6
7
8
9
Express::Express(): s(), str(0), len(0)
{}
 
Express::Express(const char *ss): s()
{
    len = strlen(ss);
    str = new char[len + 1];
    strcpy(str, ss);
}
Добавлено через 1 минуту
Цитата Сообщение от viktorius Посмотреть сообщение
если я убираю Stack()
Покажите этот класс. Конструктор по умолчанию там есть?
viktorius
2 / 2 / 2
Регистрация: 24.02.2013
Сообщений: 105
28.12.2013, 06:25  [ТС] #5
Цитата Сообщение от alsav22 Посмотреть сообщение
Конструкторы не создают объекты, они инициализируют поля.
да свои поля и

если полем класса является какой нибудь класс то нужно же создать объект этого класса (в классе) т.е. вызвать конструктор этого класса например при наследовании или композиции чтоб например передать ему параметры

но по сути ошибка в неправильном вызове конструктора шаблонного класса, прочитал тему шаблонов у Герберта Шилдта и Харви Дейтела Пол Дейтела, но там нет примеров похожих на мой случай

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
template <class T> class Stack
{
    T *st;
    int top, m;
public:
    Stack();
    ~Stack();
    void Push(T);
    T Pop();
    int Gettop();
};
 
template <class T> Stack<T>::Stack(): st(0), top(0), m(0)
{}
 
template <class T> Stack<T>::~Stack()
{
    delete [] st;
}
 
template <class T> void Stack<T>::Push(T ch)
{
    if(m && !(m - top))
    {
        T *t = st;
        st = new T[m += n];
        for(int i = 0; i <= top; i++)
            st[i] = t[i];
        delete [] t;
    }
    else if(!m)
    {
        m = n;
        st = new T[m];
    }
    st[top++] = ch;
}
 
template <class T> T Stack<T>::Pop()
{
    if(m && (m - top > n + n))
    {
        T *t = st;
        st = new T[m -= n];
        for(int i = 0; i <= top; i++)
            st[i] = t[i];
        delete [] t;
    }
    return st[top--];
}
 
template <class T> int Stack<T>::Gettop()
{
    return top;
}
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.12.2013, 06:27 #6
Цитата Сообщение от viktorius Посмотреть сообщение
если полем класса является какой нибудь класс то нужно же создать объект этого класса (в классе) т.е. вызвать конструктор этого класса например при наследовании или композиции чтоб например передать ему параметры
Ещё раз:
Цитата Сообщение от alsav22 Посмотреть сообщение
Конструкторы не создают объекты, они инициализируют поля. Объект Stack <char> s будет создан при создании объекта Express
Для создания объекта (выделения под него памяти) конструктор не нужен.
viktorius
2 / 2 / 2
Регистрация: 24.02.2013
Сообщений: 105
28.12.2013, 06:31  [ТС] #7
выложил класс стек

C++
1
2
3
4
5
6
7
8
9
Express::Express(): s(), str(0), len(0)
{}
 
Express::Express(const char *ss): s()
{
    len = strlen(ss);
    str = new char[len + 1];
    strcpy(str, ss);
}
так выдает ошибку Ошибка 2 error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall Stackt<char>::Stackt<char>(void)" (??0?$Stackt@D@@QAE@XZ) в функции "public: __thiscall Express::Express(void)" (??0Express@@QAE@XZ) express.obj
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.12.2013, 06:33 #8
Вот этот код у меня ошибок не выдаёт:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
template <class T> class Stack
{
    T *st;
    int top, m;
public:
    Stack();
    ~Stack();
    void Push(T);
    T Pop();
    int Gettop();
};
 
template <class T> Stack<T>::Stack(): st(0), top(0), m(0)
{}
 
template <class T> Stack<T>::~Stack()
{
    delete [] st;
}
 
template <class T> void Stack<T>::Push(T ch)
{
    if(m && !(m - top))
    {
        T *t = st;
        st = new T[m += n];
        for(int i = 0; i <= top; i++)
            st[i] = t[i];
        delete [] t;
    }
    else if(!m)
    {
        m = n;
        st = new T[m];
    }
    st[top++] = ch;
}
 
template <class T> T Stack<T>::Pop()
{
    if(m && (m - top > n + n))
    {
        T *t = st;
        st = new T[m -= n];
        for(int i = 0; i <= top; i++)
            st[i] = t[i];
        delete [] t;
    }
    return st[top--];
}
 
template <class T> int Stack<T>::Gettop()
{
    return top;
}
 
 
class Express
{
    Stack <char> s;
    char *str;
    int len;
public:
    Express();
    Express(const char *);
};
 
Express::Express(): str(0), len(0)
{}
 
Express::Express(const char *ss)
{
    len = strlen(ss);
    str = new char[len + 1];
    strcpy(str, ss);
}
 
int main()
{
    Express exp;
}
У вас шаблон и реализация в одном файле находятся? Должны быть в одном. У вас, скорее всего, ошибка именно поэтому. Компоновщик не находит реализацию конструктора по умолчанию.
viktorius
2 / 2 / 2
Регистрация: 24.02.2013
Сообщений: 105
28.12.2013, 06:37  [ТС] #9
нет все раздельно в 5 файлах
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.12.2013, 06:41 #10
Цитата Сообщение от viktorius Посмотреть сообщение
нет все раздельно в 5 файлах
Из-за этого и ошибка. На будущее (касается только шаблонов): объявление и реализация должны быть в одном файле.

Добавлено через 2 минуты
Про работу конструктора можете здесь почитать: http://www.cyberforum.ru/blogs/18334/blog103.html
viktorius
2 / 2 / 2
Регистрация: 24.02.2013
Сообщений: 105
28.12.2013, 06:45  [ТС] #11
и еще я только учусь, в книгах пишут что поля вложенного или базового класса должны быть инициализированы через конструктор, но это было без шаблонов

например

конструктор Manager вызывает конструктор Employee
C++
1
2
3
4
Manager::Manager(): Employee(), sub(0)
{
    cout<<"Manager new"<<endl;
}
получается с шаблонами это не нужно делать?
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.12.2013, 06:55 #12
Цитата Сообщение от viktorius Посмотреть сообщение
получается с шаблонами это не нужно делать?
Шаблоны тут не при чём.
Цитата Сообщение от viktorius Посмотреть сообщение
конструктор Manager вызывает конструктор Employee
И Manager производный от Employee. Так? У вас в коде разве есть наследование? Это во-первых. Во-вторых, если написапть так:
C++
1
2
3
4
Manager::Manager(): sub(0)
{
    cout<<"Manager new"<<endl;
}
, то будет то же самое, только конструктор по умолчанию вызывается не явно. Если нужно инициализировать конструктором не по умолчанию, то его уже нужно явно вызывать.

Добавлено через 3 минуты
Как в вашем коде вызвать явно конструктор по умолчанию, я показал в 4 посте:
C++
1
2
3
4
5
6
7
8
9
Express::Express(): s(), str(0), len(0)
{}
 
Express::Express(const char *ss): s()
{
    len = strlen(ss);
    str = new char[len + 1];
    strcpy(str, ss);
}
Добавлено через 1 минуту
Ссылку, про работу конструкторов, я вам выложил. Читайте.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.12.2013, 06:55
Привет! Вот еще темы с ответами:

Повторный вызов конструктора класса - C++
class X { public: X() {a = 10;}; setA(int value) {a = value;}; private: int a; };

Непонятный вызов конструктора класса - C++
Почему в строчке d1=500; (70 стр.) вызывается конструктор CDate(500, 1, 2000)? Получается, целое число 500 перед присваиванием каким то...

Вызов конструктора родительского класса - C++
Здравствуйте, столкнулся с такой проблемой: при вызове конструктора класса потомка (Derv1) через наследование конструктора из базового...

Вызов конструктора из родительского класса - C++
Как вызвать конструктор для производного класса из родительского?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
28.12.2013, 06:55
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru