#c #class #operator-overloading #overloading #forward-declaration
#c #класс #оператор-перегрузка #перегрузка #forward-объявление
Вопрос:
ЦЕЛЬ:
Целью этого кода является преобразование долларов в центы и центов в доллары (и наоборот).
ПРОБЛЕМА:
Проблема с этим кодом заключается в том, что преобразование из долларов в центы и наоборот происходит только в одну сторону. Если вы удалите строку, operator Dollars() const {return Dollars(m_cents / 100);}
, код работает отлично, но в одностороннем порядке.
Прямое объявление класса не работает и возвращает C2027 «Использование неопределенного типа ‘Dollars'». Почему в этом случае не работает пересылка объявления класса? Похоже, это проблема циклической зависимости.
РЕШЕНИЕ:
Что нужно сделать, чтобы решить эту проблему?
#include <iostream>
class Cents;//forward declare Cents for Dollar conversion
class Dollars;
class Cents
{
private:
int m_cents;
public:
Cents(int cents = 0)
: m_cents{ cents }
{
}
// Overloaded int cast
operator int() const { return m_cents; }
//int getCents() const { return m_cents; }
//void setCents(int cents) { m_cents = cents; }
//Convert Cents into Dollars. C2027 error.
operator Dollars() const
{
return Dollars(m_cents / 100);
}//myown
};
class Dollars
{
private:
int m_dollars;
public:
Dollars(int dollars = 0)
: m_dollars{ dollars }
{
}
// Overloaded int cast
operator int() const
{
return m_dollars;
}//myown
//int getDollars() const { return m_dollars; }//myown
//void setDollars(int dollars) { m_dollars = dollars; }//myown
// Allow us to convert Dollars into Cents
operator Cents() const
{
return Cents(m_dollars / 100);
} //This won't work because it hasn't seen class Cents
};
void printCents(Cents cents)
{
std::cout << cents << " cents"; // cents will be implicitly cast to an int here
}
void printDollars(Dollars dollars)
{
std::cout << dollars << " dollars";//myown
}
int main()
{
//Dollars dollars{ 9 };
//printCents(dollars); // dollars will be implicitly cast to a Cents here. You get 900 cents
Cents cents{ 2000 };//myown
printDollars(cents);//myown
std::cout << 'n';
return 0;
}
Комментарии:
1. Вы не можете создать
Dollar
объект, если у вас нет полного определения класса. Выделите функции и реализуйте их за пределами определения класса.
Ответ №1:
Такого рода проблемы могут быть устранены путем перемещения реализации в файл cpp. Таким образом, вы можете включить необходимые заголовки без циклических зависимостей :
В долларах.hpp
operator Cents() const;
В центах.hpp
operator Dollars() const;
В Dollars.cpp
#include Cents.hpp
Dollars::operator Cents() const
{
return Cents(m_dollars / 100);
}
В Cents.cpp
#include Dollars.hpp
Cents::operator Dollars() const
{
return Dollars(m_cents / 100);
}
Редактировать :
Если вы хотите сохранить все в одном файле, как в вашем примере, просто замените текущие определения объявлениями :
operator Cents() const;
operator Dollars() const;
И переместите реализации за пределы классов, например, над функцией main() :
Dollars::operator Cents() const
{
return Cents(m_dollars / 100);
}
Cents::operator Dollars() const
{
return Dollars(m_cents / 100);
}
int main() { /* ... */ }
Комментарии:
1. Привет, dspr, похоже, это не работает. Я прикрепил то, что я сделал в основном потоке.
2. Я не вижу, что вы изменили, извините. Но взгляните на мою правку, я показываю, как это исправить при работе с одним файлом, как в вашем примере: я протестировал его, и он работает.
3. оператор Cents() const; оператор Dollars() const; Приведенное выше приведет к «Синтаксической ошибке ошибки C2059:’новая строка'».
4. Я не могу воспроизвести этот результат, выполнение (в одном файле) печатает «20 долларов» и завершается без каких-либо ошибок. Обратите внимание также, что эти две строки не следуют друг за другом в реальных кодах : первая находится в классе Cents (где она заменяет ваше первоначальное определение), а вторая — в классе Dollars (idem). Это то, что вы сделали?
5. Я пытался решить с помощью вашего метода, но я просто не смог его решить. Спасибо за помощь.