c++ - 使用 Makefile 在多个文件 C++ 中构建互连类

标签 c++ class build makefile

我不太熟悉从 makefile 构建更复杂的 C++ 程序(我通常使用 IDE 或只做简单的 C 而没有面向对象的编程)。当类在多个文件上相互连接时,我不知道如何做 makefile。

简单示例:如何将这个单文件程序拆分成单独的文件并使用 Make 构建它:

#include <math.h>

// I want to move this into Vec3d.h
class Vec3d{
    double x,y,z;
    inline void set( const double fx, const double fy, const double fz ) { x=fx; y=fy; z=fz;         }
    inline Vec3d& operator+=( const double& f ) { x+=f; y+=f; z+=f; return *this; }
    inline Vec3d  operator* ( const double& f ) const { Vec3d vo; vo.x=x*f; vo.y=y*f; vo.z=z*f; return vo; }
    // ... other operators omited for shorness
}

// I want to move this into Body.h
class Body{
    double mass;
    Vec3d pos,velocity,force; // use Vect3d
    void getForce(){};
    void move( double dt ){ // use operators defined in Vec3d
        getForce();
        v   += force * -dt;
        pos += v   *    dt;
    }
}

// I want to move this into Planet.h
class Planet : public Body{
    void getForce( ){ // overrides method from "Body"
        double r = sqrt( pos.dot(pos) ) ;
        force = pos * ( -dt/(ir*ir*ir) );
    }
}

// This should be in main.cpp
Vec3d  myVector;
Body   myBody;
Planet myPlanet;
main(){
    // ...do something with myVector, myBody and myPlanet
}

一个选择是#include everything into main.cpp。然而,这很糟糕,因为它会一直重新编译所有内容。

我宁愿只重新编译我更改的文件,其余的则取自 .o 文件。但是要独立编译 Body.h,我必须将#include Vec3d.h 放入其中。所以 Vec3d.h 在 main.cpp 中会被包含两次,这就造成了冲突。

我知道在 C 中头文件用于此目的,但如果可能的话,当我想在类主体中定义方法和运算符时,我不知道如何在 C++ 中使用它(它使程序更具可读性,就像在 Java 中一样)。

最佳答案

好的,所以我想通了,抱歉新手问题。唯一的问题是,对于 Vec3d,必须直接在 .h 文件中声明内联方法。整个解决方案是:

生成文件

all: program

program: main.o Planet.o Body.o
    g++ main.o Planet.o Body.o -o program

main: main.cpp
    g++ -c main.cpp

Body.o: Body.cpp
    g++ -c Body.cpp 

Planet.o: Planet.cpp
    g++ -c Planet.cpp 

clean:
    rm -rf *o hello

主要.cpp:

#include "Vec3d.h"
#include "Body.h"
#include "Planet.h"
Vec3d  myVector;
Body   myBody;
Planet myPlanet;
int main(){
    myVector.set(1);
    myBody.pos.set(1);
    myBody.move(0.1);
    myPlanet.getForce();
    myPlanet.move(0.1);
}

星球.h:

class Planet : public Body{
    public:
    void getForce( );
    //void move( );
};

星球.cpp:

#include <math.h>
#include "Vec3d.h"
#include "Body.h"
#include "Planet.h"
void Planet::getForce()      {
    double r = sqrt( pos.mag2() );
    force    = pos * ( mass/(r*r*r) );
}

正文.h:

class Body{
    public:
    // parameters
    double mass;
    // state variables
    Vec3d pos,vel;
    // temporary variables
    Vec3d force;
    // methods
    void getForce();
    void move( double dt );
};

正文.cpp:

#include "Vec3d.h"
#include "Body.h"
void Body::getForce(){ force.set(0); };
void Body::move( double dt ){
    vel  += force * dt;
    pos  += vel   * dt;
}

Vec3d.h:

// NOTE: "inline" methods must be implemented directly here
class Vec3d{
    public:
    double x,y,z;
    inline void set( const double  f         ) { x=f; y=f; z=f; };
    inline void set( const Vec3d&  v          ) { x=v.x; y=v.y; z=v.z; };
    inline void set( const double fx, const double fy, const double fz ) { x=fx; y=fy; z=fz; };

    inline Vec3d& operator =( const double f ) { x=f; y=f; z=f; return *this; };
    inline Vec3d& operator+=( const double f ) { x+=f; y+=f; z+=f; return *this; };
    inline Vec3d& operator*=( const double f ) { x*=f; y*=f; z*=f; return *this; };
    inline Vec3d& operator+=( const Vec3d&  v ) { x+=v.x; y+=v.y; z+=v.z; return *this; };
    inline Vec3d& operator-=( const Vec3d&  v ) { x-=v.x; y-=v.y; z-=v.z; return *this; };
    inline Vec3d& operator*=( const Vec3d&  v ) { x*=v.x; y*=v.y; z*=v.z; return *this; };
    inline Vec3d& operator/=( const Vec3d&  v ) { x/=v.x; y/=v.y; z/=v.z; return *this; };
    inline Vec3d operator+ ( const double f ) const { Vec3d vo; vo.x=x+f; vo.y=y+f; vo.z=z+f; return vo; };
    inline Vec3d operator* ( double f ) const { Vec3d vo; vo.x=x*f; vo.y=y*f; vo.z=z*f; return vo; };

    inline Vec3d operator+ ( const Vec3d& vi ) const { Vec3d vo; vo.x=x+vi.x; vo.y=y+vi.y; vo.z=z+vi.z; return vo; };
    inline Vec3d operator- ( const Vec3d& vi ) const { Vec3d vo; vo.x=x-vi.x; vo.y=y-vi.y; vo.z=z-vi.z; return vo; };
    inline Vec3d operator* ( const Vec3d& vi ) const { Vec3d vo; vo.x=x*vi.x; vo.y=y*vi.y; vo.z=z*vi.z; return vo; };
    inline Vec3d operator/ ( const Vec3d& vi ) const { Vec3d vo; vo.x=x/vi.x; vo.y=y/vi.y; vo.z=z/vi.z; return vo; };

    inline void fma( const double f, const Vec3d& b ){ x+=f*b.x; y+=f*b.y; z+=f*b.z;       };

    inline void fma( const Vec3d& a, const Vec3d& b ){ x+=a.x*b.x; y+=a.y*b.y; z+=a.z*b.z; };
    inline void fms( const Vec3d& a, const Vec3d& b ){ x-=a.x*b.x; y-=a.y*b.y; z-=a.z*b.z; };
    inline void fda( const Vec3d& a, const Vec3d& b ){ x+=a.x/b.x; y+=a.y/b.y; z+=a.z/b.z; };
    inline void fds( const Vec3d& a, const Vec3d& b ){ x-=a.x/b.x; y-=a.y/b.y; z-=a.z/b.z; };

    inline Vec3d fma_func( const double f, const Vec3d& b ){ Vec3d vo; vo.x=x+f*b.x;   vo.y=y+f*b.y;   vo.x=z+f*b.z;   return vo; };
    inline Vec3d fma_func( const Vec3d& a, const Vec3d& b ){ Vec3d vo; vo.x=x+a.x*b.x; vo.y=y+a.y*b.y; vo.z=z+a.z*b.z; return vo; };
    inline Vec3d fms_func( const Vec3d& a, const Vec3d& b ){ Vec3d vo; vo.x=x-a.x*b.x; vo.y=y-a.y*b.y; vo.z=z-a.z*b.z; return vo; };
    inline Vec3d fda_func( const Vec3d& a, const Vec3d& b ){ Vec3d vo; vo.x=x+a.x/b.x; vo.y=y+a.y/b.y; vo.z=z+a.z/b.z; return vo; };
    inline Vec3d fds_func( const Vec3d& a, const Vec3d& b ){ Vec3d vo; vo.x=x-a.x/b.x; vo.y=y-a.y/b.y; vo.z=z-a.z/b.z; return vo; };

    inline double dot ( const Vec3d& a ){ return x*a.x + y*a.y + z*a.z;  };
    inline double mag2(                ){ return x*x+y*y+z*z;            };

    inline void  cross     ( const Vec3d& a ){ double _x=y*a.z-z*a.y;   double _y=z*a.x-x*a.z; z=x*a.y-y*a.x;     x=_x; y=_y;  };
    inline Vec3d cross_func( const Vec3d& a ){ Vec3d vo; vo.x=y*a.z-z*a.y; vo.y=z*a.x-x*a.z; vo.z=x*a.y-y*a.x;   return vo;   };

};

关于c++ - 使用 Makefile 在多个文件 C++ 中构建互连类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26422122/

相关文章:

c++ - 如何将 double 转换为 float 指针?

c++ - 使用文件中的数据在对话框中显示多个图像 (C++ MFC)

c++ - C++ 类中的 private const 是多余的吗?

mysql - 如何在 Ant 中查找可执行文件的路径

java - 无法解析不同风格android studio的方法 'getAllUserGroupByName()'

c++ - 如何使用 system() 函数在 C++ 程序中设置路径

c++ - 不同类别的 vector

javascript - ES2015 (ES6) 类中类构造函数的闭包

python - "module.__init__() takes at most 2 arguments (3 given)"创建子类实例时

python - 构建Python : how to disable Py_LIMITED_API?