如何正确地将一个.cpp文件拆分为.cpp和.h文件

4

我对将.cpp文件拆分为.cpp和.h文件的操作非常陌生。

我以前使用过.h文件,但从未真正将.cpp文件拆分为.cpp和.h文件。

我知道.h文件仅用于声明,而.cpp文件用于定义,我尝试将.cpp文件拆分为.cpp和.h文件,但是出现了很多错误,所以我想知道是否有人可以帮助我检查我的代码。

以下是尚未拆分为.cpp和.h文件的类,只是为了向大家展示“之前的版本”。

TicketOrder.cpp

#include <iostream>

using namespace std;

class TicketOrder
{

private :

        char type;
        int quantity;

public :

          friend std::ostream& operator<<(std::ostream& os, TicketOrder const& order)
         {
                 os << " Type: " << order.type << ", Quantity: " << order.quantity;
                 return os;
         }


        //Getters

        int getQuantity() const;
         {
                        return quantity;
         }

        char getType() const;
          {
                        return type;
          }

        //Setters    

        void setQuantity (int x)
                {
                        quantity =x;
                }

        void setType(char y)
                {
                        type =y;
                }   
};

现在,我将把上面的类分成一个.cpp文件和一个.h文件。
TicketOrder.cpp
#include <iostream>
#include "TicketOrder.h"
using namespace std;

class TicketOrder
{

        //Getters

        int getQuantity() const
                {
                        return quantity;
                }

        char getType() const
                {
                        return type;
                }

        //Setters

        void setQuantity (int x)
                {
                        quantity =x;
                }

        void setType(char y)
                {
                        type =y;
                }        
};

TicketOrder.h

#include <iostream>

using namespace std;

class TicketOrder
{

private :

        char type;
        int quantity;

public :

          friend std::ostream& operator<<(std::ostream& os, TicketOrder const& order)
        {
                 os << " Type: " << order.type << ", Quantity: " << order.quantity;
                 return os;
        }

        //Getters

        int getQuantity() const;    
        char getType() const;

        //Setters

        void setQuantity (int x);    
        void setType(char y);       
};

我还有一个类用来包含主类,因为它很长并且我认为它不重要,所以我不会在这里包含它。当我尝试编译主类时,会出现以下错误:

Undefined                       first referenced
 symbol                             in file
TicketOrder::getQuantity() const    /var/tmp//ccaSflFG.o
TicketOrder::setType(char)          /var/tmp//ccaSflFG.o
TicketOrder::setQuantity(int)       /var/tmp//ccaSflFG.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status

有人能帮我拆分.h和.cpp文件吗?或者给我建议?我做了很多研究,但是不知道哪里出了问题。

谢谢。


1
  1. 使用最简单的例子
  2. 不要过多地使用空格
  3. 不要重复声明“TicketOrder”。
- Beta
1
重复声明类是可以的(看起来像 class TicketOrder;,但这里有一个重复的定义)。 - Ben Voigt
@BenVoigt,你是对的,我改正我的错误。 - Beta
4个回答

4

你的.cpp文件有误,因为它重新声明了类,所以会出现错误。应该像下面这样:

#include <iostream>
#include "TicketOrder.h"
using namespace std;

//Getters
int TicketOrder::getQuantity() const
{
    return quantity;
}
char TicketOrder::getType() const
{
    return type;
}

//and so on

此外,需要注意的是,在头文件中添加 using namespace,就像你正在做的那样,被认为是非常糟糕的风格。

1
问题出在类的第二个定义 - Ben Voigt
大家好,我已经阅读了你们的建议并删除了重复的类定义,但是当我编译它时,仍然收到与我上面发布的错误相同的错误。我改变的唯一一件事是在TicketOrder.cpp类中删除了重复的类定义。有人知道发生了什么吗?我不明白那个错误告诉我的是什么。 :/ - r1nzler
@r1nzler,你试过跟随 Rodrigo 的例子吗? - Beta
当我这样编译它:g++ ticket.cpp TicketOrder.cpp,它会给我这些错误:TicketOrder.cpp:5: 错误:非成员函数'int getQuantity()'不能有cv限定符 TicketOrder.cpp:6: 错误:在标记“{”之前应该是未限定的ID TicketOrder.cpp:12: 错误:非成员函数'char getType()'不能有cv限定符 TicketOrder.cpp:13: 错误:在标记“{”之前应该是未限定的ID TicketOrder.cpp: 在函数'setQuantity(int)'中: TicketOrder.cpp:25: 错误:在此范围内未声明'quantity' - r1nzler
@r1nzler - 错误 non-member function 'int getQuantity()' cannot have cv-qualifier 的意思是该函数是一个非成员函数,但它应该是一个成员函数。所以你很可能忘记在名称前加上 TicketOrder:: - rodrigo
显示剩余3条评论

2
你可以使用 lzz 进行操作,它会自动完成这个过程。在默认模式下,它会显示通常放置的位置。

1
你只需注意以下几点,就可以很成功地完成这个任务:
  1. 你的.cpp文件应包含主函数
  2. 你的.h文件应包含头文件
  3. 你的.cpp文件(即程序)应在顶部声明所有头文件名
  4. 你的.h文件应包含在.h文件中使用的其他头文件
  5. 当你编译.h文件时,可能会显示一些错误,但不要担心。这是因为它不包含主函数。

0

Rodrigo已经解决了你的主要问题。让我补充一些风格上的建议:

  • 你不需要使用using namespace std,因为你已经用std::前缀来引用std成员了。在我看来,这几乎总是最好的解决方案,因为using namespace X指令可能会被一些包含你的.h文件的其他文件继承。
  • 如果你真的想使用using namespace std,请将该指令放在类内部,这样包含你的文件的其他文件就不会有它。它们可能会定义与std相同名称的函数/类,如果有一个using namespace std指令在上面,就会导致编译错误...
  • 你的.cpp文件不需要包含<iostream>,因为它已经在头文件中包含了...是的,<iostream>肯定有一个头文件保护,所以它并没有真正被包含两次。但我认为不包含已经在头文件中包含的内容是很好的...但也许这只是我的口味... ;-)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接