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

РЕДАКТИРОВАТЬ: это было отмечено как дубликат.Я считаю, что есть различие между 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 в конструктор, как это можно сделать, не создавая циклическую ссылку или не потеряв / не изменив типизацию?

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

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Не уверен, что это лучшая практика, но вы можете использовать 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;
};

ссылку Годболта: https://godbolt.org/z/ILbFpS

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

0 голосов
/ 15 декабря 2018

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

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

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

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

...