繁体   English   中英

将此 class 分离到 header 和 cpp 文件中

[英]Seperating this class into a header and cpp file

我很难将此 class 分成 header 和 .cpp 文件,因为 c++ 对我来说相对较新。 这个 class 是我的老师在 class 中与我们一起编程的示例。 这不是家庭作业,但它会帮助我理解我的家庭作业。

#include <iostream>
#include <AstUtils.h>
#include <vector>
#include <cassert>
#include <Vector2.h>

#define WIDTH 1377
#define HEIGHT 768

using namespace std;
using namespace astu;

class Stone {
public:

Stone(double x = 0, double y = 0)
    : x(x), y(y), vx(0), vy(0)
{
//empty
}
void SetPos(double x, double y){
    this->x = x;
    this->y = y;
}

void Render() {
    SetRenderColor(255,0,0);
    RenderRectangle(x,y,20,20,true);
}

double GetPosX() const {
    return x;
}

double GetPosY() const {
    return y;
}

void SetVel(double vx, double vy){
    this->vx = vx;
    this->vy = vy;
}

void SetAcc(double ax, double ay){
    this->ax = ax;
    this->ay = ay;
}

void Update(double dt) {
    x += vx*dt;
    y += vy*dt;

    vx += ax*dt;
    vy += ay*dt;

    ax = 0;
    ay = 0;
}

private:
    double x,y;
    double vx, vy;
    double ax, ay;
};


void PlotCurve(vector<double> & vertices) {
assert(vertices.size() % 2 == 0);
assert(vertices.size() >= 4);

auto it = vertices.begin();

double x1 = *it++;
double y1 = *it++;

while(it != vertices.end()){
double x2 = *it++;
double y2 = *it++;
RenderLine(x1,y1, x2, y2);
x1 = x2;
y1 = y2;
}
}

void ReportError()
{
std::cout << "An error has occured: " << GetLastErrorMessage() << std::endl;
std::cout << GetErrorDetails() << std::endl;
}

int main()
{
if (InitApp(WIDTH,HEIGHT, "Demo") != NO_ERROR) {
ReportError();
return -1;
}

Vector2<double> center(WIDTH/2, HEIGHT/2);

Stone stone(WIDTH * 0.3, HEIGHT/2);
stone.SetVel(100, -150);

vector<double> posCurve;
posCurve.push_back(stone.GetPosX());
posCurve.push_back(stone.GetPosY());

while(!IsAppTerminated()) {
    ClearCanvas();

    Vector2 p(stone.GetPosX(), stone.GetPosY());
    Vector2 d = center - p;
    double dist = d.LengthSquared();

    d.Normalize();
    d *= 50000000 / dist;

    stone.SetAcc(d.x,d.y);

    stone.Update(GetDeltaTime());
    stone.Render();

    posCurve.push_back(stone.GetPosX());
    posCurve.push_back(stone.GetPosY());
    SetRenderColor(255,255,255);
   PlotCurve(posCurve);

    UpdateApp();
}

QuitApp();

}

这是我尝试过的:

(不知道如何定义构造函数,也遇到了问题,因为变量在 header 中。)

.cpp:

Stone::Stone(double x = 0, double y = 0)
    : x(x), y(y), vx(0), vy(0)
{}

void SetPos(double x, double y){
    this->x = x;
    this->y = y;
}

void Render() {
    SetRenderColor(255,0,0);
    RenderRectangle(x,y,20,20,true);
}

double GetPosX() const {
    return x;
}

double GetPosY() const {
    return y;
}

void SetVel(double vx, double vy){
    this->vx = vx;
    this->vy = vy;
}

void SetAcc(double ax, double ay){
    this->ax = ax;
    this->ay = ay;
}

void Update(double dt) {
    x += vx*dt;
    y += vy*dt;

    vx += ax*dt;
    vy += ay*dt;

    ax = 0;
    ay = 0;
}

。H:

class Stone{
public:

    Stone(double x = 0, double y = 0);

    void SetPos(double x, double y);

    void Render();

    double GetPosX();

    double GetPosY();

    void SetVel(double vx, double vy);

    void SetAcc(double ax, double ay);

    void Update(double dt);

private:

    double x,y;
    double vx, vy;
    double ax, ay;
};

您不一定需要将所有实现移动到.cpp文件中。 当它足够短并且不使用 class 外部的任何 object 时,您可以将.hpp文件中的实现保留为内联 function。 对于像getPosXgetPosY这样的成员来说尤其如此。 内联这样的成员是一种空间增益,但也可能导致更快的代码。

我通常保留 class 声明函数,我可以在一行上编写,如下所示:

double GetPosX() const { return x; }
double GetPosY() const { return y; }

但是,如果 function 需要包含另一个 header,我将实现移动到.cpp文件以避免包含在 header 中

double GetPosX() const;
double GetPosY() const;

.cpp中:

#include AnotherClass.hpp

double Stone::GetPosX() const {  return anotherClass.x; }
double Stone::GetPosY() const {  return anotherClass.y; }

对于构造函数,您可以将其保存在 header 中,尤其是在它为空的情况下,如您的示例所示:

Stone(double x = 0, double y = 0) : x(x), y(y), vx(0), vy(0)
{}

但是,如果它是一个更复杂的实现,你也应该移动它:

// In the header
Stone(double x = 0, double y = 0);
// In the cpp
Stone::Stone(double x, double y) : x(x), y(y), vx(0), vy(0) 
{
    //Complex implementation of the constructor
}

你需要声明你在cpp中定义的函数的scope。

Header:

// use a "guard" to avoid duplicate includes in compilation units
#pragma once
// if compiler doesn't support "#pragma once" do
/*
#ifndef _classname_
#define _classname_
*/

class C {
  private:
    int a;
    static const int B;
  public:
    C(int); // ctor
    void setA(const int&);
    int getA() const;
};

/*
#endif
*/

价格:

#include <header.h>

// constants need to be defined in the compilation unit,
// because the header might be included (read: copy & pasted)
// in multiple different compilation units and suddenly
// you have a class with multiple constants
static const int C::b = 4;

// constructor with member initializer list
C::C(int a) : a(a)
{
  // empty
}

// normal function
void C::setA(const int& a) {
  this->a = a;
}

// const function
int C::getA() const {
  return a;
}

请不要在 header 文件中使用using namespace ,因为这可能会弄乱包含它们的任何人的代码。 记住#include <file>是“在此处复制文件内容”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM