我是C ++初学者,所以我正在为练习构建一个预算应用(创意,对吧?)。我正在使用CMake进行构建过程。我已经在另一个类中声明了一个类,我只有std::shared_ptr
个不完整的类,但我仍然会遇到incomplete type
个错误。这是CMake尝试在另一个类之前构建一个类的问题吗?如果是这种情况,有没有办法指定CMake Category
之前需要构建Transaction
?或者是否有关于前方声明的遗漏?
-- Configuring done
-- Generating done
-- Build files have been written to: /hdd/lfs/projects/budget/build
make[1]: Entering directory '/hdd/lfs/projects/budget/build'
make[2]: Entering directory '/hdd/lfs/projects/budget/build'
make[3]: Entering directory '/hdd/lfs/projects/budget/build'
make[3]: Leaving directory '/hdd/lfs/projects/budget/build'
make[3]: Entering directory '/hdd/lfs/projects/budget/build'
[ 16%] Building CXX object CMakeFiles/budget.dir/src/Transaction.cpp.o
/hdd/lfs/projects/budget/src/Transaction.cpp: In constructor ‘Transaction::Transaction(double, std::shared_ptr<Category>)’:
/hdd/lfs/projects/budget/src/Transaction.cpp:11:12: error: invalid use of incomplete type ‘class Category’
_category->addTransaction(*this);
^
In file included from /hdd/lfs/projects/budget/src/Transaction.cpp:3:0:
/hdd/lfs/projects/budget/include/Transaction.h:10:7: note: forward declaration of ‘class Category’
class Category;
^
/hdd/lfs/projects/budget/src/Transaction.cpp: In constructor ‘Transaction::Transaction(double, std::__cxx11::string, std::shared_ptr<Category>)’:
/hdd/lfs/projects/budget/src/Transaction.cpp:21:12: error: invalid use of incomplete type ‘class Category’
_category->addTransaction(*this);
^
In file included from /hdd/lfs/projects/budget/src/Transaction.cpp:3:0:
/hdd/lfs/projects/budget/include/Transaction.h:10:7: note: forward declaration of ‘class Category’
class Category;
^
/hdd/lfs/projects/budget/src/Transaction.cpp: In destructor ‘Transaction::~Transaction()’:
/hdd/lfs/projects/budget/src/Transaction.cpp:26:12: error: invalid use of incomplete type ‘class Category’
_category->deleteTransaction(*this);
^
In file included from /hdd/lfs/projects/budget/src/Transaction.cpp:3:0:
/hdd/lfs/projects/budget/include/Transaction.h:10:7: note: forward declaration of ‘class Category’
class Category;
^
CMakeFiles/budget.dir/build.make:158: recipe for target 'CMakeFiles/budget.dir/src/Transaction.cpp.o' failed
make[3]: *** [CMakeFiles/budget.dir/src/Transaction.cpp.o] Error 1
make[3]: Leaving directory '/hdd/lfs/projects/budget/build'
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/budget.dir/all' failed
make[2]: *** [CMakeFiles/budget.dir/all] Error 2
make[2]: Leaving directory '/hdd/lfs/projects/budget/build'
Makefile:83: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/hdd/lfs/projects/budget/build'
makefile:2: recipe for target 'all' failed
make: *** [all] Error 2
#pragma once
#include <string>
#include <list>
#include "Transaction.h"
class Category
{
private:
std::string _name;
double _budget;
double _balance;
std::list<Transaction> _transactions;
void calculateBalance();
public:
Category() =delete;
Category(std::string name)
: _name(name), _budget(0), _balance(0)
{}
std::string name() const;
void setName(std::string name);
double budget() const;
void setBudget(double budget);
double balance() const;
void addTransaction(Transaction& transaction);
void deleteTransaction(Transaction& transaction);
std::ostream& display(std::ostream& out) const;
bool operator==(const Category& right) const;
bool operator!=(const Category& right) const;
friend std::ostream& operator<<(std::ostream& out, const Category& c)
{
return c.display(out);
}
};
#pragma once
#include <iostream>
#include <memory>
#include "boost/date_time/gregorian/gregorian.hpp"
#include "DisplayHelpers.h"
class Category;
class Transaction
{
private:
std::string _description;
double _amount;
boost::gregorian::date _date;
std::shared_ptr<Category> _category;
public:
Transaction() = delete;
Transaction(double amount, std::shared_ptr<Category> category);
Transaction(double amount, std::string description,
std::shared_ptr<Category> category);
~Transaction();
void setDescription(std::string description);
std::string getDescription() const;
void setAmount(double amount);
double getAmount() const;
boost::gregorian::date getDate() const;
void setCategory(std::shared_ptr<Category> c);
std::shared_ptr<Category> getCategory() const;
bool operator==(const Transaction& other) const;
bool operator<(const Transaction& other) const;
std::ostream& display(std::ostream& out) const;
friend std::ostream& operator<<(std::ostream& out, const Transaction& t)
{
return t.display(out);
}
};
#include "Transaction.h"
Transaction::Transaction(double amount, std::shared_ptr<Category> category)
: _amount(amount),
_date(boost::gregorian::day_clock::local_day()),
_description("Transaction"),
_category(category)
{
_category->addTransaction(*this);
}
Transaction::Transaction(double amount, std::string description,
std::shared_ptr<Category> category)
: _amount(amount),
_date(boost::gregorian::day_clock::local_day()),
_description(description),
_category(category)
{
_category->addTransaction(*this);
}
Transaction::~Transaction()
{
_category->deleteTransaction(*this);
}
void Transaction::setDescription(std::string description)
{
_description = description;
}
std::string Transaction::getDescription() const
{
return _description;
}
void Transaction::setAmount(double amount) {_amount = amount;}
double Transaction::getAmount() const {return _amount;}
void Transaction::setCategory(std::shared_ptr<Category> category)
{
_category = category;
}
std::shared_ptr<Category> Transaction::getCategory() const
{
return _category;
}
std::ostream& Transaction::display(std::ostream& out=std::cout) const
{
std::string amountString = DisplayHelpers::monify(_amount);
out << std::setw(14) << std::left << "Description: " << _description << "\n";
out << std::setw(13) << std::left << "Amount: " << amountString << "\n";
out << std::setw(14) << std::left << "Date: " << _date << "\n";
return out;
}
bool Transaction::operator==(const Transaction& other) const
{
return (_description == other._description &&
_amount == other._amount &&
_date == other._date &&
_category == other._category);
}
bool Transaction::operator<(const Transaction& other) const
{
bool returnStatus = false;
if (_date > other._date)
{
returnStatus = false;
}
else
{
if (_amount < other._amount)
{
returnStatus = true;
}
}
return returnStatus;
}
答案 0 :(得分:1)
您的Transaction.cpp
文件仅包含Transaction.h
,其中不包含Category
的定义。因此,在Transaction.cpp
的上下文中,编译器不允许您访问Category
类型的任何对象的成员。在Category.h
中加入Transaction.cpp
来解决您的问题。