Как я могу передать `this` конструктору без циклических ссылок (или потери типа) в c ++?

РЕДАКТИРОВАТЬ: это было отмечено как дубликат. Я считаю, что есть различие между Q: что я могу использовать для решения своей проблемы, A: эта вещь ~ и ~ Q: что это за вещь? A: большой огромный ответ. Я не уверен, что официальное решение по этому вопросу, хотя.

У меня есть два класса, которые оба должны знать друг о друге

// Creator.h
#pragma once
#include "Creation.h"class Creator {
Creator() {
myThing = new Creation(*this);
}
int age = 42;
Creation myThing*;
}

.

// Creation.h
#pragma once
#include "Creator.h"class Creation {
Creation(Creator &whoMadeMe) {
std::cout << whoMadeMe.age;
}
}

Проблема в том, что всякий раз, когда я делаю что-то подобное, я получаю сообщение об ошибке, что того или другого еще не существует. В этом случае, Creation(Creator &whoMadeMe) выдаст ошибку Creator does not exist из-за того, что класс Creation не готов к ссылке.

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

Таким образом, в таких сценариях, где нужно пройти this указатель на конструктор, как это можно сделать, не создавая циклическую ссылку или не теряя / не изменяя типизацию?

Кроме того, если потеря / повторный набор текста является лучшим решением, пожалуйста, дайте мне знать. Мне всегда говорили избегать этого, и я предполагаю, что это не решение проблемы в результате.

1

Решение

Вам нужно разделить объявление (в файлах .h) и реализацию (в файлах .cpp). Затем используйте предварительное объявление в заголовочных файлах, чтобы предотвратить циклическую ссылку. В файлах имплементации вы можете использовать включает.

Это исправит вашу проблему, но также оптимизирует компиляцию.

Проверьте Что такое предварительные объявления в C ++? а также Разделение кода класса на заголовок и файл cpp.

Поскольку вы не используете класс, а только объявляете атрибуты или параметры как указатели или ссылки на класс, который вы можете использовать class Creator; скорее, чем #include "Creator.h"

4

Другие решения

Не уверен, что это лучшая практика, но вы можете использовать template чтобы решить это

#include <iostream>

class Creation
{
public:
template<typename Creator> // type concept of Creater
Creation(Creator &whoMadeMe)
{
std::cout << whoMadeMe.age;
}
};

class Creator
{
public:
Creator()
{
myThing = new Creation(*this);
}
int age = 42;
Creation * myThing = nullptr;
};

ссылка Godbolt: https://godbolt.org/z/ILbFpS

Кстати, использовать new внимательно. Или используйте умные указатели, чтобы облегчить жизнь.

1

Вам действительно нужна ссылка на Создателя? Если нет, просто используйте предварительную декларацию для создания и перемещения Creator Конструктор ниже Творения. Тогда все может содержаться в одном файле:

#pragma once

class Creation;

class Creator {
public:
Creator();
int age = 42;
Creation* myThing;
};

class Creation {
public:
Creation(Creator* whoMadeMe) {
std::cout << whoMadeMe->age;
}
};

Creator::Creator(){
myThing = new Creation(this);
}

Еще лучше, используйте умные указатели.

-1
По вопросам рекламы [email protected]