C++中extern声明Cite类全局对象编译报错的解决方法咨询
解决C++类未前置声明导致的全局对象编译错误
我定义了Individu和Cite两个类,在file.hpp中先声明了extern Cite CITE;,随后定义Individu类,希望在Individu实例化时将其添加到Cite类的tab向量中(因仅存在一个Cite实例,故使用extern声明全局对象)。
原头文件代码
//file.hpp #include <iostream> #include <stdexcept> #include <vector> extern Cite CITE; class Individu { protected: static int id; TYPE t; public: Individu(); virtual ~Individu(); static int & getCompteur(); virtual void afficher(std::ostream& ) const; virtual TYPE getType() const; }; class Cite { std::vector<const Individu *> tab; public: Cite(); ~Cite(); void addPersonne(const Individu *); int size() const; }; std::ostream& operator<<(std::ostream&, const Individu& ); #endif
原源文件代码
// file.cpp #include <algorithm> #include "file.hpp" int Individu::id = 0; Individu::Individu() { CITE.addPersonne(*this); id++; } Individu::~Individu(){ } int& Individu::getCompteur() { return id; } void Individu::afficher(std::ostream& o) const{ o << id; } void Personne::afficher(std::ostream& o) const { o << nom << " " << id; } std::ostream& operator<<(std::ostream& o, const Individu& i ){ i.afficher(o); return o; } TYPE Individu::getType() const { throw IllegalException(); } Cite::Cite(){ } Cite::~Cite() { } void Cite::addPersonne(const Individu * i){ tab.push_back(i); } int Cite::size() const { return tab.size(); }
编译错误信息
file.hpp:13:8: error: ‘Cite’ does not name a type 13 | extern Cite CITE; | ^~~~ file.cpp: In constructor ‘Individu::Individu()’: file.cpp:30:5: error: ‘CITE’ was not declared in this scope 30 | CITE.addPersonne(*this); | ^~~~ make: *** [makefile:15 : build/deviant.o] Erreur 1
修复方案
1. 前置声明Cite类
编译器处理extern Cite CITE;时,还不知道Cite是一个类类型,所以需要在该声明前添加类前置声明,让编译器识别这个类型:
// 在extern声明前添加 class Cite; extern Cite CITE;
2. 修正构造函数的参数类型
Individu构造函数中调用CITE.addPersonne(*this)时,参数类型不匹配:addPersonne接受const Individu*,但*this是Individu&,直接传递this指针即可:
Individu::Individu() { CITE.addPersonne(this); // 替换*this为this id++; }
3. 定义全局Cite对象
头文件中仅用extern声明了全局对象,但未在源文件中定义它,需要在file.cpp开头添加定义:
// file.cpp开头添加 Cite CITE;
4. 补充未定义的依赖(可选但必要)
代码中还存在未定义的标识符:TYPE、IllegalException、Personne,需要补充定义才能正常编译,例如:
// 在file.hpp中添加 typedef int TYPE; // 根据实际需求定义TYPE类型 class IllegalException : public std::exception {}; // 定义异常类 // 补充Personne类的定义(如果是Individu的子类) class Personne : public Individu { std::string nom; public: // 补充构造函数等成员 void afficher(std::ostream& o) const override; };
修改后的完整代码示例
修改后的file.hpp
//file.hpp #include <iostream> #include <stdexcept> #include <vector> #include <string> // 补充未定义的依赖 typedef int TYPE; class IllegalException : public std::exception {}; // 前置声明Cite类 class Cite; extern Cite CITE; class Individu { protected: static int id; TYPE t; public: Individu(); virtual ~Individu(); static int & getCompteur(); virtual void afficher(std::ostream& ) const; virtual TYPE getType() const; }; // 补充Personne类定义 class Personne : public Individu { std::string nom; public: Personne(const std::string& n) : nom(n) {} void afficher(std::ostream& o) const override; }; class Cite { std::vector<const Individu *> tab; public: Cite(); ~Cite(); void addPersonne(const Individu *); int size() const; }; std::ostream& operator<<(std::ostream&, const Individu& ); #endif
修改后的file.cpp
// file.cpp #include <algorithm> #include "file.hpp" // 定义全局Cite对象 Cite CITE; int Individu::id = 0; Individu::Individu() { CITE.addPersonne(this); id++; } Individu::~Individu(){ } int& Individu::getCompteur() { return id; } void Individu::afficher(std::ostream& o) const{ o << id; } void Personne::afficher(std::ostream& o) const { o << nom << " " << id; } std::ostream& operator<<(std::ostream& o, const Individu& i ){ i.afficher(o); return o; } TYPE Individu::getType() const { throw IllegalException(); } Cite::Cite(){ } Cite::~Cite() { } void Cite::addPersonne(const Individu * i){ tab.push_back(i); } int Cite::size() const { return tab.size(); }
内容的提问来源于stack exchange,提问作者user14598940
相关产品推荐
相关产品推荐

