У меня есть простой Vec3 класс и простой xMath класс.
Класс xMath должен изменить Vec3. Есть только 2 файла Vec3.hpp и xMath.hpp (и мне не разрешено создавать другие файлы).
xMath не признаетсяИспользование Visual Studio 2019 Community Edition.
Получение ошибок:
Используя предварительные объявления, все равно получаем ошибки:
Вот файлы.
//Vec3.hpp
#ifndef VEC3_H
#define VEC3_H
#include "xMath.hpp"
namespace ns
{
//class xMath; //forward declaration does not work either..
struct Vec3
{
public:
float x;
//constructor
Vec3(float x) { this.x = x; }
static float Change(Vec3* v)
{
v->x = xMath::Change(v);
return t;
}
};
}
#endif
//xMath.hpp
#ifndef XMATH_H
#define XMATH_H
#include "Vec3.hpp"
namespace ns
{
//class Vec3; //forward declaration does not work either..
static class xMath
{
public:
static float Change (Vec3* v)
{
return v->x;
}
};
}
#endif
"и мне не разрешено создавать другие файлы" что вам разрешено менять? Например, почему xMath является классом, если у него есть только статические методы? Может ли это быть просто вложенное пространство имен?
Хорошо, я на самом деле портирую код с другого языка, чтобы не создавать оболочку. Цель метода Change() — зависеть только от Vec3, не нужно усложнять пример. Я мог бы создать классическую пару .cpp и .h, но надеюсь, что смогу портировать код, используя только .h или .hpp, поскольку файлов более 500. Также было бы полезно зеркалировать как можно больше других файлов.
@Homer512 Homer512 Да, xMath может быть просто вложенным пространством имен, но я ищу общее решение, потому что есть и другие классы, у которых не все методы являются статическими.
Меня беспокоит вопрос «переноса с другого языка». Прямой «перевод» редко работает хорошо. Неважно, письменный, устный или языки программирования. Вместо этого запишите подробное описание поведения программы, которую вы хотите «портировать» или «перевести» (если она еще не существует, например, проектный документ), а затем переопределите ее на целевом языке, используя все возможности целевой язык.





Эти требования очень странные. Обычно мы помещаем реализацию в отдельный файл, включающий оба заголовка.
Однако мы можем сделать что-то подобное внутри заголовков:
#ifndef XMATH_H
#define XMATH_H
// First the declarations:
namespace ns
{
class Vec3;
class xMath
{
public:
static float Change (Vec3* v);
};
}
// Now the implementation (which would normally be in xMath.cpp):
#include "Vec3.hpp"
float ns::xMath::Change (Vec3* v)
{
return v->x;
}
#endif
По крайней мере, отчасти причина, по которой упреждающие объявления не сработали в предыдущем примере, заключалась в том, что Vec3 был заранее объявлен как class, но полностью объявлен как struct. Форвард-объявления должны соответствовать фактическим.
Ошибка C2027 возникает в коде, который обращается к членам класса, когда доступно только предварительное объявление. Есть существующие вопросы за 2009 , 2015 и 2017.
С помощью предварительного объявления вы можете создавать экземпляры указателей или ссылок на заранее объявленный класс. Вы не можете создать экземпляр самого класса и не можете получить доступ к его членам.
Как предположили Тоби Спейт и Пол Сандерсон, способ обеспечить доступ обоих классов к членам друг друга заключается в реализации методов классов вне каждого класса. Последовательность — это предварительные объявления, объявления классов и, наконец, реализации.
Обычно реализации метода содержатся в одном или двух файлах CPP, и эти файлы CPP включают оба файла заголовков. Если вам необходимо использовать только заголовки, вы можете поместить операторы включения после определений классов.
Такое предварительное объявление компилируется:
namespace ns
{
class XMath;
class Vec3
{
public:
float m_x;
Vec3(float x)
: m_x(x)
{}
Удалите
#include "Vec3.hpp"и переместите его в конец файлаxMath.hpp(прямо перед#endif). Затем добавьте предварительное объявлениеVec3внутри пространства именns. Затем измените функциюxMath::Change(это очень плохое название для чего-то, что на самом деле ничего не меняет), чтобы она была просто объявлением. И, наконец, определите (реализуйте) функциюxMath::Changeпосле включенияVec3.hpp.