如何在C++中正确扩展类并写入其头文件
How to correctly extend a class in C++ and writing its header file?
我有一个名为person.lib
的第三方库及其标头person.h
。这是我的实际项目结构,它可以完美编译和运行。
实际结构:
主.cpp
#include <iostream>
#include <time.h>
#include <ctype.h>
#include <string>
#include "person.h"
using namespace person;
using namespace std;
class Client : public Person
{
public:
Client();
void onMessage(const char * const);
private:
void gen_random(char*, const int);
};
Client::Client() {
char str[11];
gen_random(str, 10);
this->setName(str);
}
void Client::onMessage(const char * const message) throw(Exception &)
{
cout << message << endl;
}
void Client::gen_random(char *s, const int len) {
//THIS FUNCTION GENERATES A RANDOM NAME WITH SPECIFIED LENGTH FOR THE CLIENT
}
int main()
{
try
{
Person *p = new Client;
p->sayHello();
}
catch(Exception &e)
{
cout << e.what() << endl;
return 1;
}
return 0;
}
我想通过将我的 Client
类的声明与其定义分开来重构我的代码,并创建client.h
和client.cpp
。注意:sayHello()
和onMessage(const * char const)
是人员库的功能。
重构结构:
主.cpp
#include <iostream>
#include "client.h"
using namespace person;
using namespace std;
int main()
{
try
{
Person *p = new Client;
p->sayHello();
}
catch(Exception &e)
{
cout << e.what() << endl;
return 1;
}
return 0;
}
客户端.cpp
#include "client.h"
using namespace person;
using namespace std;
Client::Client() {
char str[11];
gen_random(str, 10);
this->setName(str);
}
void Client::onMessage(const char * const message) throw(Exception &)
{
cout << message << endl;
}
void Client::gen_random(char *s, const int len) {
//THIS FUNCTION GENERATES A RANDOM NAME WITH SPECIFIED LENGTH FOR THE CLIENT
}
客户端.h
#ifndef CLIENT_H
#define CLIENT_H
#include <time.h>
#include <ctype.h>
#include <string>
#include "person.h"
class Client : public Person
{
public:
Client();
void onMessage(const char * const);
private:
void gen_random(char*, const int);
};
#endif
如您所见,我只是创建了一个包含基类person.h
client.h
,然后我创建了包含client.h
及其函数定义的client.cpp
。现在,编译给了我这些错误:
error C2504: 'Person': base class undefined client.h 7 1 Test
error C2440: 'inizialization': unable to convert from 'Client *' to 'person::impl::Person *' main.cpp 15 1 Test
error C2504: 'Person': base class undefined client.h 7 1 Test
error C2039: 'setName': is not a member of 'Client' client.cpp 8 1 Test
error C3861: 'sendMessage': identifier not found client.cpp 34 1 Test
这只是一个剪切和复制重构,但它不起作用,我真的不明白为什么!解决方案是什么,为什么它会给我这些错误?我缺少C++结构吗?
这是一个狗鸟实现(ruff ruff, cheep cheep(cLawyer 在 main.cpp 中定义和实现,而 cPerson 和 cClient 在它们自己的头文件中定义,在他们自己的 cpp 文件中实现。更好的方法是存储类的名称。然后,就不需要重载 speak 方法 - 只需在每个派生副本中设置 className。但在我的估计中,这将提供一个不太有用的例子。
主.cpp
#include <cstdio>
#include "cClient.h"
class cLawyer : public cPerson
{
public:
cLawyer() : cPerson() {}
~cLawyer() {}
void talk(char *sayWhat){printf("cLawyer says: '%s'n", sayWhat);}
};
int main()
{
cPerson newPerson;
cClient newClient;
cLawyer newLawyer;
newPerson.talk("Hello world!");
newClient.talk("Hello world!");
newLawyer.talk("Hello $$$");
return 0;
}
cPerson.h
#ifndef cPerson_h_
#define cPerson_h_
class cPerson
{
public:
cPerson();
virtual ~cPerson();
virtual void talk(char *sayWhat);
protected:
private:
};
#endif // cPerson_h_
c人.cpp
#include "cPerson.h"
#include <cstdio>
cPerson::cPerson()
{
//ctor
}
cPerson::~cPerson()
{
//dtor
}
void cPerson::talk(char *sayWhat)
{
printf("cPerson says: '%s'n",sayWhat);
}
cClient.h
#ifndef cClient_h_
#define cClient_h_
#include "cPerson.h"
class cClient : public cPerson
{
public:
cClient();
virtual ~cClient();
void talk(char *sayWhat);
protected:
private:
};
#endif // cClient_h_
c客户端.cpp
#include "cClient.h"
#include <cstdio>
cClient::cClient()
{
//ctor
}
cClient::~cClient()
{
//dtor
}
输出
cPerson says: 'Hello world!'
cClient says: 'Hello world!'
cLawyer says: 'Hello $$$'
上述建议:
//In the cPerson class, a var
char *m_className;
//In the cPerson::cPerson constructer, set the var
m_className = "cPerson";
//Re-jig the cPerson::speak method
void cPerson::speak(char *sayWhat)
{
printf("%s says: '%s'n", m_className, sayWhat);
}
// EDIT: *** remove the speak methods from the cClient and cLawyer classes ***
//Initialize the clas name apporpriately in derived classes
//cClient::cClient
m_className = "cClient";
//Initialize the clas name apporpriately in derived classes
//cLaywer::cLaywer
m_className = "cLawyer";
您声明类 Client 两次 - 一次在 .h
文件中,一次在.cpp
中。您只需要在.h
文件中声明它。您还需要将using namespace person;
放入.h
文件。
如果类 Person 位于 namcespace person 中,请使用person::Person
访问它。
client.cpp
必须仅包含定义!
我认为对于链接器,在 client.h 中定义的类 Client 和在 client.cpp 中定义的类 Client 是不同的类,因此它找不到 Client::Client(( 的实现。我的目的是从客户端中删除类 Client 的声明.cpp只留下函数的定义:
// client.cpp
#include <time.h>
#include <ctype.h>
#include <string>
#include "client.h"
using namespace std;
Client::Client()
{
//DO STUFF
}
void Client::onMessage(const char * const message)
{
//DO STUFF
}
void Client::gen_random(char *s, const int len) {
//DO STUFF
}
- 如何按文件扩展名引用文件夹中的文件
- 谁能告诉我,程序中的错误是什么?该程序仅用于获取文件扩展名
- 通过cMake使用具有自定义文件扩展名的共享库
- 在另一个字符串中插入文件扩展名之前的字符串
- 如何在不使用文件扩展名的情况下使用命令行参数打开C++中的文本文件?
- Eclipse CDT:传递具有相同文件扩展名的多个程序参数
- 将C 代码桥接到我的Swift代码中.哪些文件扩展名为XCode中的基于C的语言
- 如何打开并显示C 中任何文件扩展名的文件
- 循环浏览所有项目,其中QTREEVIEW QFILESYSTEMMODEL上具有所需的文件扩展名
- 如何调用 ShellExecute 以使用 C++ 打开具有特定程序的文件,而无需关联相同的文件扩展名
- 使用.rose(文件扩展)CPP的文件处理
- 用户定义的C 文件扩展名,用于G 汇编
- 如何在 INFLATE 后获取原始文件扩展名
- CMake:如何仅将特定文件扩展名从一个目录复制到另一个目录
- 获取文件扩展名
- C 中的自定义数据文件扩展
- 共享库的TX文件扩展名
- 如何创建一个不敏感的正则态度以匹配文件扩展名
- 如何更改QT上的文件扩展名
- 列出 OpenCV 支持的文件扩展名