#c #class #oop #enums #member
Вопрос:
Я все еще довольно новичок в C , поэтому извините, если код немного дилетантский, это может быть источником проблемы.
Я потратил некоторое время на поиск на этом сайте и в Интернете. Существует множество примеров использования enum
s (не enum class
), а также использования enum
классов s и enum
s вне классов, но на самом деле я не нашел ничего полезного для моего конкретного сценария, см. Ниже. Конечно, я, возможно, видел ответ, но мой C еще недостаточно развит, чтобы распознать его.
В принципе, я хочу передать 2 класса «состояния» enum
в метод, в классе, отличном от тех, в которых определены классы перечислений, а затем изменить состояние второго класса перечисления на основе значения в первом классе перечисления. Эти классы перечисления определены внутри класса, который содержит указатель на второй класс, в котором определен метод. Объявления классов содержатся в файлах заголовков и определены в отдельных файлах .cpp, которые включают соответствующие заголовки. Смотрите подробный код и ошибки ниже.
Надеюсь, кто-нибудь поможет мне интерпретировать сообщения об ошибках в конце и понять, как этого добиться.
main.cpp
#include <iostream>
#include "firstfile.h"
int main() {
FirstFile firstobject;
firstobject.Function1();
}
В принципе, у меня есть 2 enum classe
ученика в следующем классе.
firstfile.h
#include "secondfile.h"
class FirstFile
{
protected:
SecondFile secondobject;
public:
enum class enum1 {
Option1,
Option2
} enumIn = enum1::Option1;
enum class enum2 {
Option3,
Option4
} enumInOut = enum2::Option3;
// Methods
protected:
public:
void Function1();
};
firstfile.cpp
#include <iostream>
#include "firstfile.h"
void FirstFile::Function1()
{
std::cout << "Before the function call enumIn = Option 1 and enumInOut = Option3 " << std::endl;
secondobject.function2(enumIn, enumInOut);
if (enumInOut == enum2::Option4) {
std::cout << "After the function call enumInOut = Option 4" << std::endl;
}
else if (enumInOut == enum2::Option3) {
std::cout << "After the function call enumInOut = Option 3" << std::endl;
}
else {
std::cout << "enumInOut didn't match either Option 3 or Option 4" << std::endl;
}
}
The header file, where most of the errors occur.
secondfile.h
#include "firstfile.h"
class SecondFile
{
public:
void function2(const enum1amp; enumIn, enum2amp; enumInOut);
};
Наконец, вот вызываемый метод в классе 2, который должен обновить enum2 на основе значения enum1.
secondfile.cpp
#include <iostream>
#include "firstfile.h"
#include "secondfile.h"
void SecondFile::function2(const enum1amp; enumIn, enum2amp; enumInOut)
{
if (enumIn == FirstFile::enum1::Option1) {
enumInOut = FirstFile::enum2::Option4;
}
}
Ошибки заключаются в следующем:
firstfile.cpp
secondfile.h(16, 28) : error C4430 : missing type specifier - int assumed.Note : C does not support default - int
secondfile.h(16, 28) : error C2143 : syntax error : missing ',' before 'amp;'
firstfile.cpp(8, 42) : error C2660 : 'SecondFile::function2' : function does not take 2 arguments
secondfile.h(16, 7) : message: see declaration of 'SecondFile::function2'
Main.cpp
secondfile.h(16, 28) : error C4430 : missing type specifier - int assumed.Note : C does not support default - int
secondfile.h(16, 28) : error C2143 : syntax error : missing ',' before 'amp;'
secondfile.cpp
secondfile.h(16, 28) : error C4430 : missing type specifier - int assumed.Note : C does not support default - int
secondfile.h(16, 28) : error C2143 : syntax error : missing ',' before 'amp;'
secondfile.cpp(5, 39) : error C4430 : missing type specifier - int assumed.Note : C does not support default - int
secondfile.cpp(5, 39) : error C2143 : syntax error : missing ',' before 'amp;'
secondfile.cpp(6, 6) : error C2065 : 'enumIn' : undeclared identifier
secondfile.cpp(7, 3) : error C2065 : 'enumInOut' : undeclared identifier
Надеюсь, что все это имеет смысл, и с нетерпением жду любых идей, которые помогут понять причину ошибок и то, как я мог бы их устранить.
Вероятно, это связано с областью применения, но я надеюсь извлечь уроки из этого опыта.
Ответ №1:
У вас есть две проблемы:
- У вас есть циклические зависимости, так как вы добавляете заголовки каждого класса в файлы заголовков друг друга. Вы можете решить эту проблему с помощью элементов указателей. Сделайте члена класса
secondobject
в классеFirstFile
указателем и предоставьте прямое объявление в заголовке (т. Е. вfirstfile.h
) дляSecondFile
. - Во-вторых, вам нужно указать
enum1
, иenum2
из какого это класса/ области. Для этого вы можете использоватьusing
спецификатор, и перечисления будут доступны для всей области действия классаSecondFile
.
Это означает, что вам нужно что-то вроде: (См. Онлайн)
firstfile.h
class SecondFile; // forward declaration
class FirstFile
{
protected:
SecondFile* secondobject{ nullptr }; // or smart pointers
public:
// ...enums and functions
};
firstfile.cpp
#include <iostream>
#include "secondfile.h"
void FirstFile::Function1()
{
// ...other code
if(secondobject)
secondobject->function2(enumIn, enumInOut);
// ^^^^^^^^^^^^
}
secondfile.h
#include "firstfile.h"
class SecondFile
{
public:
using enum1 = FirstFile::enum1; // specify from where the enums are
using enum2 = FirstFile::enum2;
void function2(const enum1amp; enumIn, enum2amp; enumInOut);
// ...other codes
};
secondfile.cpp
#include "secondfile.h"
void SecondFile::function2(const enum1amp; enumIn, enum2amp; enumInOut)
{
if (enumIn == enum1::Option1) {
enumInOut = enum2::Option4;
}
}
Комментарии:
1. Привет, спасибо вам за ваш быстрый ответ и исчерпывающий ответ. Похоже, там была пара основных ошибок (циклические зависимости) и отсутствие прямых объявлений. Думал, что объем перечислений был частью проблемы, рад, что я был прав в этом. Предоставленный вами код работает, но поскольку secondobject никогда не создается, функция никогда не вызывается. Попытался создать его, но получил ошибку из-за отсутствия указателя на класс. Не могли бы вы добавить эту строку в код?? Потрачу некоторое время на то, чтобы разобрать это, чтобы понять, как это работает. Еще раз большое спасибо.
2. Спасибо, именно туда я поместил свой код для создания secondobject, но я не использовал фигурные скобки Керли, не уверен, что когда-либо видел это раньше. Возможно, именно поэтому я получил ошибку преобразования указателя. Кроме того, почему прямая декларация обходит мою проблему с областью охвата, она связана с различными единицами перевода для 2 файлов?? Спасибо за вашу помощь.
3. Спасибо вам за вашу помощь и различные ссылки, очень полезные. Я принял ваш ответ.