Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.53/34: Рейтинг темы: голосов - 34, средняя оценка - 4.53
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59

Использование указателя на объект шаблонного класса в шаблонном классе.

12.08.2011, 10:15. Показов 7268. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Мне нужно реализовать граф. Начал с вершин и ребер, причем и ребра и вершины - шаблонные классы, для того чтобы и ребро и вершина могли содержать разные данные.
В ребре указатели на 2 вершины.

Класс вершины:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T> class Vertex {
        private: 
            char* name;
            T data;
            int index;
        public: 
            Vertex();
            Vertex(char* nam, T dat, int ind);
            ~Vertex();
            char* getName(); 
            T getData(); //возвращает данные, связанные с вершиной,
            void setName(char *nam); //задает имя вершины,
            void setData(T dat); //записывает данные data в дескриптор вершины.
    };
Класс ребра:
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
template <class TT>
class Edge {
    private:
        Vertex *v1, *v2;
        int w;
    public:
        Edge(Vertex *va, Vertex *vb) {
            v1 = va;
            v2 = vb;
        }
            Edge(Vertex *va, Vertex *vb, int ww) {
            v1 = va;
            v2 = vb;
            w = ww;
           }
           Edge(Vertex *va, Vertex *vb, int ww, TT dat) {
            v1 = va;
            v2 = vb;
            w = ww;
            data = dat;
           }
           ~Edge();
        
           int getW();
           void setW(int ww);
           TT getData();
           void setData(TT dat);
};
При попытке создать ребро с двумя ребрами:
C++
1
2
3
Vertex<int> e1("parampampam", 123, 0);
Vertex<int> e2("parampampam", 123, 1);
Edge<int> rebro(&e1, &e2);
Появляется вот такая ошибка:


1>c:\users\артем\documents\visual studio 2010\projects\kp2\kp2\Vertex.cpp(6): error C2955: Vertex: для использования класса шаблон требуется список аргументов шаблон


Подскажите, пожалуйста, в чем дело?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.08.2011, 10:15
Ответы с готовыми решениями:

Создать объект шаблонного класса в другом классе
Как создать объект шаблонного класса в другом классе и вызвать через этот объект функцию? class Products { //int meat, fruit,...

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

Определение класса в шаблонном классе
Помогите разобраться с тем, как синтаксически правильно давать определения методов подкласса шаблонного класса и методов шаблонного класса,...

26
 Аватар для Dejust
49 / 49 / 4
Регистрация: 31.01.2011
Сообщений: 156
12.08.2011, 10:28
У тебя в классе Edge объявляется куча объектов типа Vertex без списка аргументов шаблона, хотя класс Vertex - шаблонный класс

Цитата Сообщение от gretham Посмотреть сообщение
шаблонные классы, для того чтобы и ребро и вершина могли содержать разные данные.
Странное решение.. Я никогда не работал с графами (только читал о них), но для меня ребро - это абстрактная линия, которая связывает два узла, не более (т.е. на деле это указатель на узел2 из узла1)
1
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
12.08.2011, 10:31  [ТС]
Ага, с этим разобрался.

По поводу ребер - это спецификация такая.

"АТД «Дескриптор ребра графа»
Дескриптор ребра содержит поля:
v1 - дескриптор вершины, из которой исходит ребро,
v2 - дескриптор вершины, в которую входит ребро,
w - вес ребра,
data - данные, связанные с ребром"
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
12.08.2011, 11:05
C++
1
2
3
4
5
6
7
8
9
template <class TT>
class Edge {
//...........
        public:
                Edge(Vertex<TT> *va, Vertex<TT> *vb) {//вот так надо
                        v1 = va;
                        v2 = vb;
                }
//...........
1
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
12.08.2011, 21:23  [ТС]
А что, если Edge не шаблонный, а обычный класс?
Как быть в этом случае?
0
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
12.08.2011, 21:34
ну указывайте тогда явно тип:
C++
1
2
3
4
5
6
7
8
class Edge {
//...........
        public:
                Edge(Vertex<int> *va, Vertex<int> *vb) {//вот так надо
                        v1 = va;
                        v2 = vb;
                }
//...........
1
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
12.08.2011, 21:45  [ТС]
Цитата Сообщение от Kastaneda Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
template <class TT>
class Edge {
//...........
        public:
                Edge(Vertex<TT> *va, Vertex<TT> *vb) {//вот так надо
                        v1 = va;
                        v2 = vb;
                }
//...........
Не совсем то. Теперь, при такой записи
C++
1
2
3
Vertex<char*> e1("parampampam", "sdffsd", 0);
Vertex<char*> e2("pudupidu pu", "sdsfdfsd", 1);
Edge<int> rebro(&e1, &e2);
Возникает ошибка:
error C2664: Edge<TT>::Edge(Vertex<T> *,Vertex<T> *): невозможно преобразовать параметр 1 из "Vertex<T> *" в "Vertex<T> *

То есть требуется чтобы и у объекта e1, e2 и rebro совпадал тип. А нужно, чтобы можно было создавать объекты разных типов.
0
Заблокирован
13.08.2011, 04:54
Цитата Сообщение от gretham Посмотреть сообщение
Всем привет!
Мне нужно реализовать граф. Начал с вершин и ребер, причем и ребра и вершины - шаблонные классы, для того чтобы и ребро и вершина могли содержать разные данные.
В ребре указатели на 2 вершины.

Класс вершины:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T> class Vertex {
        private: 
            char* name;
            T data;
            int index;
        public: 
            Vertex();
            Vertex(char* nam, T dat, int ind);
            ~Vertex();
            char* getName(); 
            T getData(); //возвращает данные, связанные с вершиной,
            void setName(char *nam); //задает имя вершины,
            void setData(T dat); //записывает данные data в дескриптор вершины.
    };
Класс ребра:
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
template <class TT>
class Edge {
    private:
        Vertex *v1, *v2;
        int w;
    public:
        Edge(Vertex *va, Vertex *vb) {
            v1 = va;
            v2 = vb;
        }
            Edge(Vertex *va, Vertex *vb, int ww) {
            v1 = va;
            v2 = vb;
            w = ww;
           }
           Edge(Vertex *va, Vertex *vb, int ww, TT dat) {
            v1 = va;
            v2 = vb;
            w = ww;
            data = dat;
           }
           ~Edge();
        
           int getW();
           void setW(int ww);
           TT getData();
           void setData(TT dat);
};
При попытке создать ребро с двумя ребрами:
C++
1
2
3
Vertex<int> e1("parampampam", 123, 0);
Vertex<int> e2("parampampam", 123, 1);
Edge<int> rebro(&e1, &e2);
Появляется вот такая ошибка:


1>c:\users\артем\documents\visual studio 2010\projects\kp2\kp2\Vertex.cpp(6): error C2955: Vertex: для использования класса шаблон требуется список аргументов шаблон


Подскажите, пожалуйста, в чем дело?
У вас вообще непонятно, какова связь между этими классами, и какова сама структура классов. Так, например, в Edge я вижу, что вы некоторому полю с именем data присваиваете значение переменной dat. Откуда это поле data взялось? Я не вижу его определения в классе Edge.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
13.08.2011, 09:32
Цитата Сообщение от gretham Посмотреть сообщение
Не совсем то. Теперь, при такой записи

C++
1
2
3
Vertex<char*> e1("parampampam", "sdffsd", 0);
Vertex<char*> e2("pudupidu pu", "sdsfdfsd", 1);
Edge<int> rebro(&e1, &e2);
Возникает ошибка:
error C2664: Edge<TT>::Edge(Vertex<T> *,Vertex<T> *): невозможно преобразовать параметр 1 из "Vertex<T> *" в "Vertex<T> *
То есть требуется чтобы и у объекта e1, e2 и rebro совпадал тип. А нужно, чтобы можно было создавать объекты разных типов.
Вот смотри:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<class T>
class A{};
 
template<class T>
class B{
public:
    template<class TT>
    B(A<TT>*){};
};
 
int main() {
    A<int> a;
    B<char> b(&a);
}
разбирайся
1
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
13.08.2011, 22:58  [ТС]
Цитата Сообщение от Kastaneda Посмотреть сообщение
Вот смотри:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<class T>
class A{};
 
template<class T>
class B{
public:
    template<class TT>
    B(A<TT>*){};
};
 
int main() {
    A<int> a;
    B<char> b(&a);
}
разбирайся
Да, вот тут все работает как надо, но как создать в классе B объект класса A так, чтобы он тоже не был конкретным?? А что - то типа
C++
1
2
3
4
5
6
7
8
template<class T>
class B{
private:
        A<TT>* a;  //Вот про это говорю
public:
    template<class TT>
    B(A<TT>*){};
};
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
13.08.2011, 23:10
Цитата Сообщение от gretham Посмотреть сообщение
//Вот про это говорю
Для этого надо передавать TT вторым параметром шаблона
C++
1
2
3
4
5
6
7
8
9
10
11
template<typename T, typename TT>
class B{
private:
        A<TT>* a;
public:
        B(A<TT>*){};
};
 
// ...
 
B<char, int> b(&a);
0
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
13.08.2011, 23:15  [ТС]
Цитата Сообщение от Сыроежка Посмотреть сообщение
У вас вообще непонятно, какова связь между этими классами, и какова сама структура классов. Так, например, в Edge я вижу, что вы некоторому полю с именем data присваиваете значение переменной dat. Откуда это поле data взялось? Я не вижу его определения в классе Edge.
На это не обращайте внимание, быстро скопипастил)

А так - все там есть)))
0
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
13.08.2011, 23:19  [ТС]
Цитата Сообщение от grizlik78 Посмотреть сообщение
Для этого надо передавать TT вторым параметром шаблона
C++
1
2
3
4
5
6
7
8
9
10
11
template<typename T, typename TT>
class B{
private:
        A<TT>* a;
public:
        B(A<TT>*){};
};
 
// ...
 
B<char, int> b(&a);
К этому решению я приходил не раз
В том числе и шаблонный параметр в шаблоне и так далее)
Суть в том, что при этом если я создам объект класса В то это нужно будет делать так:
C++
1
B<int, int> b; //Вот тут вся проблема
А при этом если захочу засунуть объект класса A с параметром char*, то ничего не получится
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
13.08.2011, 23:45
Цитата Сообщение от gretham Посмотреть сообщение
А при этом если захочу засунуть объект класса A с параметром char*, то ничего не получится
А зачем в объект класса B<int, int> пытаться засунуть A<char*> ? Может для этого всё-таки нужно B<int, char*> ? А если нужно держать там указатели на A с произвольным параметром, то я знаю единственный способ — унаследовать A<> от нешаблонного виртуального класса и использовать полиморфизм. Только виртуальные функции ведь тоже не смогут быть шаблонными.
Ну и все достоинства/недостатки виртуальности...
Пример:
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
#include <iostream>
#include <typeinfo>
 
class A_Base
{
public:
    virtual ~A_Base() {}
    virtual void SomeFunc() { std::cout << "A_Base::SomeFunc" << std::endl; }
};
 
template<typename T>
class A : public A_Base
{
public:
    void SomeFunc() { std::cout << "A<" << typeid(T).name() << ">::SomeFunc" << std::endl; }
};
 
template<typename T>
class B
{
private:
    A_Base* a;
public:
    B(A_Base* x) : a(x) {};
    void Test() { a->SomeFunc(); }
 
};
 
int main()
{
    A<int> a1;
    A<long> a2;
    B<char> b1(&a1), b2(&a2);
    b1.Test();
    b2.Test();
}
1
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
14.08.2011, 00:10  [ТС]
Цитата Сообщение от grizlik78 Посмотреть сообщение
А зачем в объект класса B<int, int> пытаться засунуть A<char*> ? Может для этого всё-таки нужно B<int, char*> ? А если нужно держать там указатели на A с произвольным параметром, то я знаю единственный способ — унаследовать A<> от нешаблонного виртуального класса и использовать полиморфизм. Только виртуальные функции ведь тоже не смогут быть шаблонными.
Ну и все достоинства/недостатки виртуальности...
Да - да, вы правильно поняли. "держать там указатели на A с произвольным параметром".

И вот еще, я правильно понял, что "Только виртуальные функции ведь тоже не смогут быть шаблонными" это значит что я не могу определить в классе A_Base метод, который вернет значение типа параметра шаблона?

И это приведет к тому, что все методы класса A не объявленные в классе A_Base я не смогу использовать в B, так?

Если так, то вряд ли мне это подойдет.
Нет ли еще какого способа "держать там указатели на A с произвольным параметром"?
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
14.08.2011, 00:31
Цитата Сообщение от gretham Посмотреть сообщение
И вот еще, я правильно понял, что "Только виртуальные функции ведь тоже не смогут быть шаблонными" это значит что я не могу определить в классе A_Base метод, который вернет значение типа параметра шаблона?
Ну я имел в виду, что параметры и возвращаемые значения виртуальных функций не могут иметь тип параметра шаблона, так как это будет перегрузка.

Цитата Сообщение от gretham Посмотреть сообщение
И это приведет к тому, что все методы класса A не объявленные в классе A_Base я не смогу использовать в B, так?
Ага. А как можно использовать в B какие-либо функции из A, если неизвестно, есть ли там такие функции и какого типа аргументы они принимают?

Цитата Сообщение от gretham Посмотреть сообщение
Если так, то вряд ли мне это подойдет.
Нет ли еще какого способа "держать там указатели на A с произвольным параметром"?
Другого хорошего способа я не знаю. Есть ещё указатель void*, но чтобы использовать объект по такому указателю надо будет его явно приводить к указателю на конкретный тип.
0
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
14.08.2011, 00:45  [ТС]
Ладно, наверное придется обойтись без произвольного типа)

А так хотелось)))))))))))))))))
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
14.08.2011, 00:47
gretham, как Вы собираетесь с этим параметром произвольного типа работать?
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
14.08.2011, 00:48
Цитата Сообщение от gretham Посмотреть сообщение
И это приведет к тому, что все методы класса A не объявленные в классе A_Base я не смогу использовать в B, так?
Собственно указатель на A_Base всегда можно попытаться привести к конкретному классу-наследнику, тем более что можно в рантайме проверять корректность такого приведения.
Возможно если будет пример, как надо использовать невесть какую функцию из невесть какого класса, то может какая идея и родиться.
0
 Аватар для gretham
19 / 19 / 1
Регистрация: 12.08.2011
Сообщений: 59
14.08.2011, 01:07  [ТС]
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
gretham, как Вы собираетесь с этим параметром произвольного типа работать?
То есть какие методы?

Или просто для чего он мне?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.08.2011, 01:07
Помогаю со студенческими работами здесь

Хранение в map указателя на функцию-член шаблонного класса
Здравствуйте! Сделал я себе вызов написать джунгли из ООП деревьев, типо, объекты обмениваются между собой сообщениями используя их...

Объявление шаблона класса, а в классе объявляется массив шаблонного типаа
Подчеркивает не правильное объявление массива T TMP = new T; public class STCK &lt;T&gt;{ private int Len; private T STC ; ...

Как использовать объект класса, созданого в определеном классе, в другом классе
У меня такой вопрос,как использовать объект класса,созданого в определеном классе,в другом классе.У меня есть объект pl класса Player,это...

Использование фабрики для шаблонного класса
Вот класс template &lt;class T&gt; class ConcreteConverter { T _value; long long _maxValue; long long _minValue; public: ...

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru