Заблокирован
1

Циклическая ссылка h-ников, что делать?

22.10.2015, 10:18. Показов 1284. Ответов 16
Метки нет (Все метки)

есть два h-ника ссылающиеся друг на друга, дело в том что в них есть классы использующие друг друга (переменные в классах), поэтому они должны ссылаться друг на друга, в итоге куча ошибок компиляции... #pragma once подключено везде где только можно, но это не помогает что делать?

Добавлено через 8 минут
например

Header.h
C++
1
2
3
4
5
6
7
8
#pragma once
#include "Header1.h"
 
class B
{
public:
    A a;
};
Header1.h
C++
1
2
3
4
5
6
7
8
9
10
#pragma once
#include "Header.h"
 
class A
{
public:
    // Ошибка C3646   b: неизвестный спецификатор переопределения
    // Ошибка C4430   отсутствует спецификатор типа - предполагается int.
    B b;
};
Source.cpp
C++
1
2
3
4
5
6
7
#pragma once
#include "Header.h"
#include "Header1.h"
 
int main()
{
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.10.2015, 10:18
Ответы с готовыми решениями:

Неизвестная ошибка сборки, Ссылка не указывает на объект экземпляра, что делать?
Сабж. Такое происходит во всех проектах, независимо от того, какие элементы я разместил в окне....

Циклическая ссылка
Всем привет! Недавно наткнулся на статью в блоге компании Mail.ru. Так вот, там описываются...

Циклическая ссылка при попытке получить данные из контроллера
при попытке получить данные из контроллера в формате JSON выбрасывает исключение "циклическая...

Что делать с этой ошибкой: "LNK2019: ссылка на неразрешенный внешний символ _WinMain@16"?
Ошибка 1 error LNK2019: ссылка на неразрешенный внешний символ _WinMain@16 в функции...

16
Модератор
Эксперт С++
12631 / 10128 / 6098
Регистрация: 18.12.2011
Сообщений: 27,159
22.10.2015, 10:18 2
Используйте предварительное объявление класса
C++
1
2
3
4
5
6
class B;
 
class A
{
  B* pb;// теперь можно объявлять указатели и/или ссылки на класс B
};
Естественно, нельзя создавать экземпляр класса B b; Это будет ошибкой, т.к. B->A->B->A и т.д. зациклимся
0
Заблокирован
22.10.2015, 10:20  [ТС] 3
zss, а как то по другому можно? не удобно же... да и все равно ошибку выдает:
Ошибка C2079 "A::b" использует неопределенный class "B"
0
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
22.10.2015, 10:23 4
C++
1
2
3
4
5
6
7
#pragma once
 
class B
{
public:
    A a;
};
C++
1
2
3
4
5
6
7
#pragma once
 
class A
{
public:
    B b;
};
C++
1
2
3
4
5
6
7
#pragma once
#include "Header.h"
#include "Header1.h"
 
int main()
{
}
Добавлено через 1 минуту
Цитата Сообщение от zss Посмотреть сообщение
B* pb;// теперь можно объявлять указатели и/или ссылки на класс B
и ещё теперь на один унылый костыль стало больше.

не нужно делать форварды там,
где предметная область такова,
что классы должны знать друг о друге.
0
Модератор
Эксперт С++
12631 / 10128 / 6098
Регистрация: 18.12.2011
Сообщений: 27,159
22.10.2015, 10:23 5
Еще раз, надо B* b; УКАЗАТЕЛЬ!!!!!!
0
Заблокирован
22.10.2015, 10:24  [ТС] 6
hoggy, эмм ну и? взяли мой код, убрали инклуды, а откуда по вашему первый h-ник узнает о существовании класса A, а второй B?

Добавлено через 35 секунд
Цитата Сообщение от zss Посмотреть сообщение
Еще раз, надо B* b; УКАЗАТЕЛЬ!!!!!!
а мне не надо указатель, мне надо объект
0
Модератор
Эксперт С++
12631 / 10128 / 6098
Регистрация: 18.12.2011
Сообщений: 27,159
22.10.2015, 10:24 7
hoggy, Использование указатель не требует знания классов друг о друге.
0
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
22.10.2015, 10:24 8
Цитата Сообщение от zss Посмотреть сообщение
Еще раз, надо B* b; УКАЗАТЕЛЬ!!!!!!
ещё раз - костыли не нужны.
0
Модератор
Эксперт С++
12631 / 10128 / 6098
Регистрация: 18.12.2011
Сообщений: 27,159
22.10.2015, 10:24 9
Объект создавайте в конструкторе!
А лучше объясните, что Вы хотите от этих классов.
У меня подозрение, что на самом деле Вам нужно наследование с виртуальными функциями.
0
Заблокирован
22.10.2015, 10:28  [ТС] 10
Цитата Сообщение от zss Посмотреть сообщение
Объект создавайте в конструкторе!
Ошибка C2512 B: нет подходящего конструктора по умолчанию

Добавлено через 1 минуту
Цитата Сообщение от zss Посмотреть сообщение
А лучше объясните, что Вы хотите от этих классов.
У меня подозрение, что на самом деле Вам нужно наследование с виртуальными функциями.
ванга мод активейтед? нет, наследование мне не нужно
0
Модератор
Эксперт С++
12631 / 10128 / 6098
Регистрация: 18.12.2011
Сообщений: 27,159
22.10.2015, 10:28 11
Объясните, что Вы хотите от этих классов.
0
Заблокирован
22.10.2015, 10:29  [ТС] 12
Цитата Сообщение от zss Посмотреть сообщение
Объясните, что Вы хотите от этих классов.
ничего не буду объяснять это секрет, вам это не обязательно знать чтобы помочь мне
0
Модератор
Эксперт С++
12631 / 10128 / 6098
Регистрация: 18.12.2011
Сообщений: 27,159
22.10.2015, 10:31 13
Ну тогда мне и не обязательно помогать Вам...
Вот пример инициализации через конструктор
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class B;
 
class A
{  
    B* pb;
public:
  A(B* t){pb=t;}
};
class B
{
    int x;
public:
    B(int k):x(k){}
};
int main ()
{
    B b(777);
    A a(&b);
}
0
Заблокирован
22.10.2015, 10:42  [ТС] 14
Цитата Сообщение от zss Посмотреть сообщение
Ну тогда мне и не обязательно помогать Вам...
ну и не помогайте блин, чего тогда вообще заходили

Добавлено через 10 минут
Цитата Сообщение от zss Посмотреть сообщение
Вот пример инициализации через конструктор
так это же уже вообще другое, у вас нету в классе B переменной типа A...
0
Модератор
Эксперт С++
12631 / 10128 / 6098
Регистрация: 18.12.2011
Сообщений: 27,159
22.10.2015, 10:54 15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class B;
 
class A
{  
    B* pb;
public:
  A(B* t){pb=t;}
};
class B
{
    A* pa;
    int x;
public:
    B(int k,A* t):x(k){pa=t;}
};
int main ()
{
    A* tmp;
    B b(777,tmp);
    A a(&b);
}
Или скорее так:
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
#include<math.h>
#include<conio.h>
#include<stdio.h>
class B;
 
class A
{  
    B* pb;
public:
    A():pb(NULL){}
  A(B* t){pb=t;}
};
class B
{
    A* pa;
    int x;
public:
    B(int k,A*& t):x(k){pa=new A;t=pa;}
};
int main ()
{
    A* tmp;
    B b(777,tmp);
// теперь tmp адресует b.pa
     A a(&b);
}
Но опять-таки - это экстрасенсорные предположения о том, что Вы хотите от такого странного кода
0
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
22.10.2015, 20:35 16
Цитата Сообщение от zss Посмотреть сообщение
Использование указатель не требует знания классов друг о друге.
это нормально, если изначально по смыслу требовался бы указатель.

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

то бишь есть маленький объект.
хотелось сделать его обычным мембером.
на стеке бы он аллоцировался и конструировался бы мгновенно.

ан, нет, pimpl толкает поюзать тормозную new/delete,
и все потому, что на плюсах не осилили моральные форварды.

можно конечно глянуть в сторону шаблоно-storage,
которые умеют аллоцировать в стековом хранилище.

что-то вроде boost::optional, например
это все ведет к некоторому усложнению кода.
но зато может уберечь от динамической памяти и не платить за то,
что не заказывали.
0
Эксперт С++
4978 / 3085 / 456
Регистрация: 10.11.2010
Сообщений: 11,164
Записей в блоге: 10
22.10.2015, 21:25 17
Цитата Сообщение от Volrajas Посмотреть сообщение
есть два h-ника ссылающиеся друг на друга, дело в том что в них есть классы использующие друг друга (переменные в классах), поэтому они должны ссылаться друг на друга, в итоге куча ошибок компиляции... #pragma once подключено везде где только можно, но это не помогает что делать?
Ничего не делать. В такой постановке тебе ничего не поможет.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.10.2015, 21:25
Помогаю со студенческими работами здесь

Циклическая ссылка (A circular reference was detected while serializing an object of type 'tblProduct')
Подскажите в чем проблема,спасибо. Есть вспомогательный класс public class ListObjectsFromDB...

подскажите что делать при вводимых данных 10 25 и 5 20 программа работает не правильно должна выводить 135 подскажите что делать
Вывод В выходной файл выведите одно число - сколько ударов сделали часы за этот отрезок времени.

Что лучше сквозная ссылка или одна статейная ссылка с одного домена?
Что лучше сквозная ссылка или одна статейная ссылка с одного домена?

Что делать, когда не знаешь, что делать?
Что делать, когда не знаешь, что делать?


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru