将C++中的类分离为头文件和源文件。

7
如何将类分隔到多个文件?以下是我目前的理解:
  1. 创建新的类,并为其创建一个“.h”文件和一个“.cpp”文件。
  2. 在主源文件中使用 #include classname.h 导入其内容。
  3. 源文件开头的 Classname::Classname 是作用域解析运算符。
  4. 通过使用已声明的对象,您可以从 main 调用函数。
我只是对如何实际实现感到困惑。我已经创建了一个包含所有类的工作计算器程序源文件。
#include <iostream>
using namespace std;

class Addition {
    public:
    float add(float x, float y) {
        float sum;
        sum = x + y;
        return sum;
    }
};

class Subtraction {
    public:
    float subtract(float x, float y) {
        float dif;
        dif = x - y;
        return dif;
    }
};

class Multiplication {
    public:
    float multiply(float x, float y) {
        float prod;
        prod = x * y;
        return prod;
    }
};

class Division {
    public:
    float divide(float x, float y) {
        float quot;
        quot = x / y;
        return quot;
    }
};

int op;
char cont;

int main() {
    do {
    cout << "Welcome to C++ Calculator v2!" << endl;
    cout << "Select the number for which operation you want to use: " << endl;
    cout << "1-Addition" << endl;
    cout << "2-Subtraction" << endl;
    cout << "3-Mutliplication" << endl;
    cout << "4-Division" << endl;
    cin >> op;

    if (op == 1) {
        float num1;
        float num2;
        Addition addObj;
        cout << "You have chosen Addition!" << endl;
        cout << "Enter the first number you want to add: " << endl;
        cin >> num1;
        cout << "Enter the second number you wat to add: " << endl;
        cin >> num2;
        float ans = addObj.add(num1, num2);
        cout << "The sum is " << ans << endl;
        cout << "Do you wish to continue? Y/N" << endl;
        cin >> cont;
    }

    if (op == 2) {
        float num1;
        float num2;
        Subtraction subObj;
        cout << "You have chosen Subtraction!" << endl;
        cout << "Enter the first number you want to subtract: " << endl;
        cin >> num1;
        cout << "Enter the second number you want to subtract: " << endl;
        cin >> num2;
        float ans = subObj.subtract(num1, num2);
        cout << "The difference is " << ans << endl;
        cout << "Do you wish to continue? Y/N" << endl;
        cin >> cont;
    }

    if (op == 3) {
        float num1;
        float num2;
        Multiplication multObj;
        cout << "You have chosen Multiplication!" << endl;
        cout << "Enter the first number you want to multiply: " << endl;
        cin >> num1;
        cout << "Enter the second number you want to multiply: " << endl;
        cin >> num2;
        float ans = multObj.multiply(num1, num2);
        cout << "The product is " << ans << endl;
        cout << "Do you wish to continue? Y/N" << endl;
        cin >> cont;
    }

    if (op == 4) {
        float num1;
        float num2;
        Division divObj;
        cout << "You have chosen Division!" << endl;
        cout << "Enter the first number you want to divide: " << endl;
        cin >> num1;
        cout << "Enter the second number you want to divide: " << endl;
        cin >> num2;
        float ans = divObj.divide(num1, num2);
        cout << "The quotient is " << ans << endl;
        cout << "Do you wish to continue? Y/N" << endl;
        cin >> cont;
    }

    } while (cont == 'Y' || cont == 'y');

    if (cont == 'N' || 'n') {
    cout << "Thanks for using my program, goodbye!" << endl;
    }

    return 0;
}

我知道有更简单的方法来做这样的事情,但是为了练习,我选择使用类和对象。

1
请编辑您的帖子以便更好地阅读。 - gaussblurinc
1
你需要将声明(.h)文件和实现(.cpp)文件分开。 - Damian
3
既然你是初学者,这里有一个提示:每次你复制/粘贴(在你的代码中经常出现),都要三思而后行:你是否在重复功能?如果是,请将该功能放入单独的函数或类中。 - stijn
好的,这与问题无关@rhalbersma,我只是为那些看到我尝试学习类和对象的帖子的人提供信息。 - Carpetfizz
@Carpetfizz 如果与你的问题无关,请不要提及。你应该尽可能简洁地提出问题。 - TemplateRex
显示剩余4条评论
4个回答

8

好的,我将为您做一个例子:

subtraction.h

class Subtraction 
{
public:
 float subtract (float x, float y);
};

subtraction.cxx

#include "subtraction.h"

float Subtraction::subtract (float x, float y)
{     
  float dif;
  dif=x-y;
  return dif;    
}

multiplication.h

class Multiplication 
{
public:
  float multiply (float x, float y);
};

multiplication.cxx

#include "multiplication.h"

float Multiplication::multiply (float x, float y)
{
  float prod;
  prod=x*y;
  return prod;
}

主程序.cxx

#include "subtraction.h"
#include "multiplication.h"

int main()
{
 //use the classes just as before.
}

此外,为了简单起见,我没有在此处放置代码,但请养成确保您的声明仅包含一次的习惯。在大型项目中,如果您不加入这些保障措施,情况可能会变得非常糟糕。
#ifndef SUBTRACTION_H
#define SUBTRACTION_H

class Subtraction
{
     ....
};
#endif /*SUBTRACTION_H*/

哇,非常感谢!!!这让我对很多事情有了更清楚的认识!感谢你抽出时间为我写下这些内容。此外,我假设“.cxx”和“.cpp”是一样的东西? - Carpetfizz
@Carpetfizz 应该是 #include "Addition.h" 而不是 #include <Addition.h>。另外,编译器可能是大小写敏感的,所以你需要确保所有的字母都正确地大写。 - Jonathan Henson
@Carpetfizz <> 包含系统头文件,"" 包含自定义头文件。无论如何,在同一个 #include 指令中不要混合使用 < 和 "。此外,我强烈建议放弃 "using namespace" 指令,而是使用完全限定的类型名称。这也会在大型项目中引起问题,并且对于其他人在多个文件项目中阅读更加困难。 - Jonathan Henson
好的,我会记住这个,是的,那些符号让我有些摸不着头脑,由于我需要为几个操作重复这个过程,我想我会掌握它的! - Carpetfizz
@Carpetfizz 不用,没关系。你可以标记任何有帮助的内容,以及你认为能引导未来的读者朝着正确方向前进的内容。 - Jonathan Henson
显示剩余4条评论

2

这里有一个类似于Jonathan示例的东西(出于简洁起见,我没有添加包含保护,但一定要添加!),但是删除了一些重复内容并添加了一些面向对象编程,以供您学习。请注意,虽然这绝不是实际计算器的实现方式,但如果您足够努力地学习它,它将帮助您更好地理解C++。

mathoperation.h:

  //a base class!
class MathOperation
{
public:
  virtual float doit( float x, float y ) const = 0;
};

subrtaction.h:

class Subtraction : public MathOperation
{
public:
  float doit( float x, float y ) const;
};

addition.h:

class Addition : public MathOperation
{
public:
  float doit( float x, float y ) const;
};

subtraction.cpp:

#include "subtraction.h"
float Subtraction::doit( float x, float y ) const { return x - y; }

addition.cpp:

#include "addition.h"
float Subtraction::doit( float x, float y ) const { return x + y; }

main.cpp:

#include <iostream>
#include <string>
  //yes this saves typing, but there reasons not to use it.. search SO!
using namespace std;

  //this one avoids you having to copy/paste the similar parts
void DoIt( const MathOperation& op, const std::string& opName, const std::string& verb, const std::string& resultName )
{
  cout << "You have chosen " << opName << "!" << endl;

  cout<<"Enter the first number you want to " << verb << ": "<< endl;

    //here you should actually check if the user really types in a number, and not    "blablabla"
    //and off course, put it in a seperate function so you can reuse it for num2
  float num1;
  cin>>num1;

  float num2;
  cout<<"Enter the second number you wat to " << verb << ": "<< endl;
  cin>>num2;

  cout<<"The " << resultName << " is " << op.doit( num1, num2 ) <<endl;
}

int main()
{
int op;
char cont = 'n';

do {
  cout<<"Welcome to C++ Calculator v2!"<<endl;
  cout<<"Select the number for which operation you want to use: "<<endl;
  cout<<"1-Addition"<<endl;
  cout<<"2-Subtraction"<<endl;
  cout<<"3-Mutliplication"<<endl;
  cout<<"4-Division"<<endl;
  cin>>op;

    //see how much shorter this is?
  if( op == 1 )
    DoIt( Addition(), "Addition", "add", "sum" );
  else if (op==2)
    DoIt( Subtraction(), "Subtraction", "subtract", "difference" );
  else
    cout << "Sorry I don't know this number" << endl;

  cout<<"Do you wish to continue? Y/N"<<endl;
  cin>>cont;

} while (cont=='Y'||cont=='y');

cout<<"Thanks for using my program, goodbye!"<<endl;
return 0;
}

1
我认为这是关于设计、继承或多态性的有益建议,但不确定它是否适用于此处,因为可能会使事情变得混乱。无论如何,我喜欢它,这是很好的建议。+1 - Jonathan Henson
非常感谢你,Stijn!这将是我一个很好的学习工具。在SO上,我是否可以“检查”多个答案? - Carpetfizz
没有别的答案了。但是别忘了选择@JonathanHenson的答案,因为他回答得又快又准确,正好解答了你的问题。我只是因为有些无聊,觉得你很渴望学习,所以添加了一些建议和内容 : ] - stijn
嗨,Stijn,感谢你让我不必为无法选择你们两个而感到难过 :) 我希望你知道你给了我和John一样多的知识,并且当我准备学习更高级的类概念时,会回来看你的答案。再次感谢你们两个! - Carpetfizz

0

把文件名和类名取得一样是个好主意。但在你的情况下,这个主意不太适用,因为你的类很短小。但每个类都应该有自己的两个文件 - 例如Subtraction.h和Subtraction.cpp。在.h文件中,你只需要放置声明 - 在你的情况下:

class Subtraction { public: float subtract (float , float); }

在.cpp文件中,你需要包含.h文件并进行实现。在你的情况下:

float Substraction::subtract (float x, float y) { float dif; dif=x-y; return dif; }

还可以参考C++头文件,代码分离为什么在C++中要有头文件和.cpp文件?

希望这对你有所帮助! :)


嗯,这让事情变得更清晰了,谢谢!我会尝试实现它,看看它会带我去哪里。 - Carpetfizz
1
float Substraction::subtract(float x, float y) { return x-y; } } 这样就可以了。或者至少立即初始化临时变量,而不是先声明它,然后再在下一行赋值给它。 - stijn

0

每个文件最好只有一个公共类。

按照惯例,文件名与类名相同(如果在文件中进行了一些定义,则带有扩展名如.h、.hh或.hpp)。

如果您想将不同的类放在不同的文件中,可以使用简单的文本编辑器来完成。


谢谢你的提示,那么我该如何使用文本编辑器呢?你是指用于复制和粘贴吗? - Carpetfizz
在IDE中有两个主要的不同部分,编辑和编译执行代码。对于编辑部分,您可以使用任何文本编辑器,从记事本到emacs(vi、np++、geny等)。或者其他IDE...对于编译,使用单独的编译器或IDE中的编译器...个人而言,我通常使用makefiles或cmake和emacs进行C++开发(但这真的很老派,我不太喜欢IDE)。 - N4553R

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