Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/29: Рейтинг темы: голосов - 29, средняя оценка - 4.69
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
1

Класс-шаблон создание конструктора по умолчанию

11.04.2015, 18:05. Показов 5595. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Хочу создать класс-шаблон. Начал с создания конструктора по умолчанию, с этого же момента и началась проблема, причём такая, что смысл её даже не понятен)))

Почему-то не создаёт Elements <int> A;
В чём может быть проблема?
С меня "спасибо" и "лучший ответ" за правильно данный ответ.

Вот код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
//файл main.cpp
#include <iostream>
#include <locale>
#include "Elements.h"
 
int main()
{
    Elements <int> A;
    //A.Add(5.);
 
    return 0;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//файл Elements.h
#pragma once
template <class T> 
class Elements
{
    //T Array;      //массив
    int razmer;     //какой должен быть размер массива
    int count;      //кол-во заполненных элементов в массив Array
    char *name;     //название множества
public:
    Elements();         //Конструктор по умолчанию
    Elements(char *, int);          //Конструктор
    void ShowArray();   //показать весь массив
    void Add(T);        //Добавить элемент в массив
    void ShowElement(); //Посмотреть, есть ли в массиве Array тот элемент, который мы запрашиваем
    //T operator=(&T);
    //T operator*(&T, &T);
    ~Elements();
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//файл Elements.cpp
#include "Elements.h"
 
const int n = 10;
 
template <class T>
Elements<T>::Elements()
{
    name = new char[n]
    name = "NoneName";
    int razmer = 10;
    T Array[n];
    count = 0;
}
Вот ошибка, которая возникает при компиляции, при нажатии на неё ни на что ни ссылается...
Миниатюры
Класс-шаблон создание конструктора по умолчанию  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.04.2015, 18:05
Ответы с готовыми решениями:

Класс содержит более одного конструктора по умолчанию
Имеется класс: class ControlObject { private: string productsFilename; ofstream fout;...

Класс содержит более одного конструктора по умолчанию
Есть класс Abonent Как мне создать массив объектов с контруктором по умолчанию? я делаю так ...

Создание лог файла. Нет подходящего конструктора по умолчанию
Добрый день, почему вылетает ошибка не пойму. Ошибка: нет подходящего конструктора по умолчанию. И...

Буст сериализация. указатель на абстрактный базовый класс без конструктора по умолчанию
Читая документацию по сериализации с помощью буста запутался. Ситуация следующая. Имеется...

21
244 / 164 / 133
Регистрация: 30.09.2012
Сообщений: 690
11.04.2015, 18:08 2
BabaSveta, в данном случае, определение конструктора (и других public функций) должно быть в .h ,а не в .cpp
1
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
11.04.2015, 18:10 3
BabaSveta, реализацию конструктора, как и остальных методов шаблона, надо перенести в h-файл. Соль в том, что шаблон должен быть доступен в точке использования полностью, чтобы компилятор смог сгенерировать по нему конкретную реализацию.
0
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
11.04.2015, 18:43  [ТС] 4
перенёс, всё равно ошибка..
C++
1
2
3
4
5
6
7
8
9
10
11
12
//файл main.cpp
#include <iostream>
#include <locale>
#include "Elements.h"
 
int main()
{
    Elements <int> A;
    //A.Add(5.);
 
    return 0;
}
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
//файл Elements.h
#pragma once
template <class T> 
class Elements
{
    //T Array;      //массив
    int razmer;     //какой должен быть размер массива
    int count;      //кол-во заполненных элементов в массив Array
    char *name;     //название множества
public:
    Elements();         //Конструктор по умолчанию
    Elements(char *, int);          //Конструктор
    void ShowArray();   //показать весь массив
    void Add(T);        //Добавить элемент в массив
    void ShowElement(); //Посмотреть, есть ли в массиве Array тот элемент, который мы запрашиваем
    //T operator=(&T);
    //T operator*(&T, &T);
    ~Elements();
};
 
 
 
const int n = 10;
 
template <class T>
Elements<T>::Elements()
{
    name = new char[n];
    name = "NoneName";
    int razmer = 10;
    T Array[n];
    count = 0;
}
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
11.04.2015, 18:48 5
Лучший ответ Сообщение было отмечено BabaSveta как решение

Решение

Цитата Сообщение от BabaSveta Посмотреть сообщение
перенёс, всё равно ошибка..
Нужно перенести все методы, а не только конструктор.
1
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
11.04.2015, 18:56  [ТС] 6
перенёс абсолютно все, и даже удалил файл Elements.cpp, но всё равно возникает ошибка..
C++
1
2
3
4
5
6
7
8
9
10
11
12
//файл main.cpp
#include <iostream>
#include <locale>
#include "Elements.h"
 
int main()
{
    Elements <int> A;
    //A.Add(5.);
 
    return 0;
}
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
//файл Elements.h
#pragma once
template <class T> 
class Elements
{
    //T Array;      //массив
    int razmer;     //какой должен быть размер массива
    int count;      //кол-во заполненных элементов в массив Array
    char *name;     //название множества
public:
    Elements();         //Конструктор по умолчанию
    Elements(char *, int);          //Конструктор
    void ShowArray();   //показать весь массив
    void Add(T);        //Добавить элемент в массив
    void ShowElement(); //Посмотреть, есть ли в массиве Array тот элемент, который мы запрашиваем
    //T operator=(&T);
    //T operator*(&T, &T);
    ~Elements();
};
 
 
 
const int n = 10;
 
template <class T>
Elements<T>::Elements()
{
    name = new char[n];
    name = "NoneName";
    int razmer = 10;
    T Array[n];
    count = 0;
}
 
//template <class T>
//Elements::Elements(char *Name, int Razmer)
//{
//  name = new char[n];
//  strcpy(Name,name);
//
//  razmer = Razmer;
//  count = 0;
//
//  T Array[razmer];
//}
 
//template <class T>
//Elements<T>::Add(T  a)
//{
//  if(count < razmer)
//  {
//      Array[count] = a;
//      count++;
//  }
//  else
//      cout << "Массив переполнен" << endl;
//}
ошибка ни на что не ссылается..
Миниатюры
Класс-шаблон создание конструктора по умолчанию  
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
11.04.2015, 19:04 7
Цитата Сообщение от BabaSveta Посмотреть сообщение
перенёс абсолютно все, и даже удалил файл Elements.cpp, но всё равно возникает ошибка..
Что-то ты мудришь. В приведенном фрагменте не видно ни реализации конструктора, ни остальных методов. Как ты мог их перенести, если их нет? Естественно он их не находит при компоновке.
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
//файл Elements.h
#pragma once
template <class T>
class Elements
{
    //T Array;      //массив
    int razmer;     //какой должен быть размер массива
    int count;      //кол-во заполненных элементов в массив Array
    char *name;     //название множества
public:
    Elements();         //Конструктор по умолчанию
    Elements(char *, int);          //Конструктор
    void ShowArray();   //показать весь массив
    void Add(T);        //Добавить элемент в массив
    void ShowElement(); //Посмотреть, есть ли в массиве Array тот элемент, который мы запрашиваем
    //T operator=(&T);
    //T operator*(&T, &T);
    ~Elements();
};
 
const int n = 10;
 
template <class T>
Elements<T>::Elements()
{
    name = new char[n];
    name = "NoneName";
    int razmer = 10;
    T Array[n];
    count = 0;
}
 
template <class T>
Elements<T>::Elements(char *Name, int Razmer)
{
    //добавить реализацию
}
 
template <class T>
void Elements<T>::Add(T a)
{
    //добавить реализацию
}
 
template <class T>
Elements<T>::~Elements()
{
    //добавить реализацию
}
Остальные методы тоже нужно сделать, само собой.
0
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
11.04.2015, 19:06  [ТС] 8
всё, решилось! Спасибо!))) Сейчас проставлю вам "Спасибо"!
0
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
11.04.2015, 20:57  [ТС] 9
При добавлении элемента с помощью метода Add выводит ошибку, смысл её понять не могу, уже менял тип принимаемых значений и тип класса, всё равно одно и то же...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//файл main.cpp
#include <iostream>
#include <locale>
#include "Elements.h"
 
int main()
{
    Elements <int> A;
    Elements <float> B("название");
    //int a= 5;
    A.Add(5);
 
    return 0;
}
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
//файл Elements.h
#pragma once
#include <iostream>
 
using namespace std;
const int n = 10;
 
template <class T> 
class Elements
{
    T Array[n];     //массив
    //int razmer;       //какой должен быть размер массива
    int count;      //кол-во заполненных элементов в массив Array
    char *name;     //название множества
public:
    Elements();         //Конструктор по умолчанию
    Elements(char *);           //Конструктор
    //void ShowArray(); //показать весь массив
    void Add(T &);      //Добавить элемент в массив
    //void ShowElement();   //Посмотреть, есть ли в массиве Array тот элемент, который мы запрашиваем
    //T operator=(&T);
    //T operator*(&T, &T);
    //~Elements();
};
 
 
 
template <class T>
Elements<T>::Elements()
{
    name = new char[n];
    name = "NoneName";
    //int razmer = 10;
    T Array[n];
    count = 0;
}
 
template <class T>
Elements<T>::Elements(char *Name)
{
    name = new char[n];
    strcpy(name,Name);
 
    count = 0;
 
    T Array[n];
}
 
template <class T>
Elements<T>::Add(T &a)
{
    if(count < razmer)
    {
        Array[count] = a;
        count++;
    }
    else
        cout << "Массив переполнен" << endl;
}
Нажимая на ошибку, программа ссылается на 59-ю строчку файла Elements.h
Миниатюры
Класс-шаблон создание конструктора по умолчанию  
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
11.04.2015, 21:11 10
Цитата Сообщение от BabaSveta Посмотреть сообщение
Нажимая на ошибку, программа ссылается на 59-ю строчку файла Elements.h
Тип возвращаемого значения добавь. В моем примере выше это сделано, кстати.
0
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
12.04.2015, 16:23  [ТС] 11
кажется не так прописываю оператор присваивания. Где именно ошибка?

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
//файл Elements.h
#pragma once
#include <iostream>
 
using namespace std;
const int n = 10;
 
template <class T> 
class Elements
{
    T Array[n];     //массив
    //int razmer;       //какой должен быть размер массива
    int count;      //кол-во заполненных элементов в массив Array
    char *name;     //название множества
public:
    Elements();         //Конструктор по умолчанию
    Elements(char *);   //Конструктор явный
    void ShowArray();   //показать весь массив
    void Add(T);        //Добавить элемент в массив
    void ShowElement(const T);  //Посмотреть, есть ли в массиве Array тот элемент, который мы запрашиваем
    Elements operator=(Elements <T> &obj);  //оператор присваивания
    //T operator*(&T, &T);
    //~Elements();
};
 
 
template <class T>
Elements Elements<T>::operator=(const Elements<T> &obj)
{
    if(this==&obj)
        return *this;
    else
        count = obj;
}
сам оператор ещё не дописал, т.к. даже не могу обратиться к obj...
Почему не могу обратиться, не понимаю..
Миниатюры
Класс-шаблон создание конструктора по умолчанию  
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
12.04.2015, 16:30 12
Лучший ответ Сообщение было отмечено BabaSveta как решение

Решение

BabaSveta, Банальная невнимательность.
В классе (забыл const у параметра, возвращать надо ссылку):
C++
1
Elements & operator=(const Elements &obj);  //оператор присваивания
В определении (параметр шаблона у типа возвращаемого значения нужен, а вот у аргумента как раз необязателен)
C++
1
2
3
4
5
6
7
8
template <class T>
Elements<T> & Elements<T>::operator=(const Elements &obj)
{
    if(this != &obj)
        count = obj;
 
    return *this;
}
1
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
12.04.2015, 16:52  [ТС] 13
Спасибо! Фиг поймёшь где его ставить
0
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
13.04.2015, 14:31  [ТС] 14
При копировании атрибута name в операторе присваивания возникает такая ошибка

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
//файл Elements.h
#pragma once
#include <iostream>
 
using namespace std;
const int n = 10;
 
template <class T> 
class Elements
{
    T Array[n];     //массив
    //int razmer;       //какой должен быть размер массива
    int count;      //кол-во заполненных элементов в массив Array
    char *name;     //название множества
public:
    Elements();         //Конструктор по умолчанию
    Elements(char *);   //Конструктор явный
    void ShowArray();   //показать весь массив
    void Add(T);        //Добавить элемент в массив
    void ShowElement(const T);  //Посмотреть, есть ли в массиве Array тот элемент, который мы запрашиваем
    Elements & operator=(const Elements &obj);  //оператор присваивания
    //T operator*(&T, &T);
    //~Elements();
};
 
template <class T>
Elements<T> & Elements<T>::operator=(const Elements &obj)
{
    if(this==&obj)
        return *this;
    else{
        count = obj.count;
        
        for(int i=obj.count-1; i>=0; i--){
            Array[i] = obj.Array[i];
        }
        strcpy(name, obj.name);                //ВОТ ЗДЕСЬ ВЫХОДИТ ЭТА ОШИБКА
    }
}
Ставлю "спасибо" и "лучший ответ", если кто-нибудь укажет на мою ошибку..
Миниатюры
Класс-шаблон создание конструктора по умолчанию  
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
13.04.2015, 14:36 15
Цитата Сообщение от BabaSveta Посмотреть сообщение
strcpy(name, obj.name);
под name не выделена память
C++
1
name = new char[strlen(obj.name) + 1];
0
1 / 1 / 1
Регистрация: 17.10.2014
Сообщений: 153
13.04.2015, 14:45  [ТС] 16
но в конструкторе по умолчанию и в явном конструкторе я её выделял... Ещё раз выделять? Что-то тогда ничего не могу понять....
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//файл Elements.h
#pragma once
#include <iostream>
 
using namespace std;
const int n = 10;
 
template <class T> 
class Elements
{
    T Array[n];     //массив
    //int razmer;       //какой должен быть размер массива
    int count;      //кол-во заполненных элементов в массив Array
    char *name;     //название множества
public:
    Elements();         //Конструктор по умолчанию
    Elements(char *);   //Конструктор явный
    void ShowArray();   //показать весь массив
    void Add(T);        //Добавить элемент в массив
    void ShowElement(const T);  //Посмотреть, есть ли в массиве Array тот элемент, который мы запрашиваем
    Elements & operator=(const Elements &obj);  //оператор присваивания
    Elements(const Elements &obj);//конструктор копирования
    //T operator*(&T, &T);
    //~Elements();
};
 
 
 
template <class T>
Elements<T>::Elements()
{
    name = new char[n];
    name = "NoneName";
    //int razmer = 10;
    T Array[n];
    count = 0;
}
 
template <class T>
Elements<T>::Elements(char *Name)
{
    name = new char[n];
    strcpy(name,Name);
 
    count = 0;
 
    T Array[n];
}
 
template <class T>
void Elements<T>::Add(T a)
{
    if(count < n)
    {
        Array[count] = a;
        count++;
    }
    else
        cout << "Массив переполнен" << endl;
}
 
 
template <class T>
void Elements<T>::ShowArray()
{
    cout << this->name << endl;
    for(int i = count-1; i>=0; i--){
        cout << Array[i] << " ";
    }
    cout << endl << endl;
}
 
template <class T>
void Elements<T>::ShowElement(T seach)
{
    for(int i = count-1; i>=0 ;i--)
    {
        if(seach==Array[i]){
            cout << "Элемент " << seach <<" в массиве " << "'" << this->name << "'" <<  " найден" << endl;
            return;
        }
    }
    cout << "Элемент в массиве не найден.." << endl;
}
 
template <class T>
Elements<T> & Elements<T>::operator=(const Elements &obj)
{
    if(this==&obj)
        return *this;
    else{
        count = obj.count;
        
        for(int i=obj.count-1; i>=0; i--){
            Array[i] = obj.Array[i];
        }
        strcpy(name, obj.name);
    }
}
 
//Elements(const Elements &obj);//конструктор копирования
 
template <class T>
Elements<T>::Elements(const Elements &obj)
{
    name = new char[n];
    strcpy(name,obj.name);
 
    count = obj.count;
    T Array[n];
 
    for(int i=obj.count-1; i>=0; i--){
            Array[i] = obj.Array[i];
    }
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//файл main.cpp
#include <iostream>
#include <locale>
#include "Elements.h"
 
int main()
{
    setlocale(LC_ALL, "rus");
 
    Elements <int> A("asd");
    Elements <double> B("название");
    Elements <int> C;
    A.Add(5); A.Add(6); A.Add(7); A.Add(8);
    B.Add(1.); B.Add(3.7); B.Add(3.8); B.Add(3.2);
    C=A;
    A.ShowArray();
    B.ShowArray();
 
    B.ShowElement(3.8);
    C.ShowArray();
    system("pause");
    return 0;
}
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
13.04.2015, 14:59 17
Лучший ответ Сообщение было отмечено BabaSveta как решение

Решение

Цитата Сообщение от BabaSveta Посмотреть сообщение
name = new char[n];
name = "NoneName";
угу Выделили, а потому указатель поменяли на указатель в памяти под константный строковый литерал
хотя бы так сделайте
C++
1
2
name = new char[n]; 
strcpy(name, "NoneName");;
1
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
13.04.2015, 15:24 18
Цитата Сообщение от BabaSveta Посмотреть сообщение
T Array[n];
Кстати, вот эта запись в каждом конструкторе бессмысленна в данном контексте. Ты определяешь локальный массив, который уничтожится по выходу из конструктора. И что это дает? Ничего.
1
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
13.04.2015, 15:34 19
DrOffset, ну так то по идее при присваивании надо name удалять(потому что даже в деф.констркуторе выделяется память), косяком много...
0
DrOffset
13.04.2015, 15:42     Класс-шаблон создание конструктора по умолчанию
  #20

Не по теме:

Цитата Сообщение от aLarman Посмотреть сообщение
ну так то по идее при присваивании надо name удалять(потому что даже в деф.констркуторе выделяется память), косяком много...
Ты это не мне говори :) А автору. Я не лезу в это, раз уж ты взялся помогать, вот и объясняй :)

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.04.2015, 15:42

Реализация конструктора по умолчанию
Добрый день. Помогите разобраться с теорией. В книге говорится, что для каждого класса в программе...

Генерация конструктора по умолчанию
Структура с множеством полей:struct MyStruct { int getVal() const {return a1+a2;} int...

Параметры конструктора по умолчанию
Привет! Подскажите, что я делаю не так. Создал класс Monstr, как в книжке написано, вот исходники:...

Инициализация конструктора по умолчанию
почему если инициализировать поля класса в конструкторе по умолчанию так: MyClass::MyClass() {...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru