Как передать класс перечисления, который находится внутри функции другого класса, по ссылке?

#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. Спасибо вам за вашу помощь и различные ссылки, очень полезные. Я принял ваш ответ.