如何在C++中正确扩展类并写入其头文件

How to correctly extend a class in C++ and writing its header file?

本文关键字:文件 扩展 C++      更新时间:2023-10-16

我有一个名为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.hclient.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
}