我很难将这个类分成头文件和 .cpp 文件,因为 C++ 对我来说相对较新。这门课是我的老师在课堂上给我们编程的一个例子。这不是家庭作业,但它会帮助我理解我的家庭作业。
#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();
}
这是我试过的:
(不知道如何定义构造函数,也有问题,因为变量在标题中。)
.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;
};
答案 0 :(得分:1)
您不一定需要将所有实现移动到 .cpp
文件中。当它足够短并且不使用类外部的任何对象时,您可以将实现作为内联函数保留在 .hpp
文件中。对于 getPosX
或 getPosY
等成员尤其如此。内联这样的成员会增加空间,但也可能会导致代码速度更快。
我通常保留可以在一行中编写的类声明函数,如下所示:
double GetPosX() const { return x; }
double GetPosY() const { return y; }
但是,如果函数需要包含另一个标头,我会将实现移到 .cpp
文件中以尽可能避免包含在标头中:
double GetPosX() const;
double GetPosY() const;
在.cpp
中:
#include AnotherClass.hpp
double Stone::GetPosX() const { return anotherClass.x; }
double Stone::GetPosY() const { return anotherClass.y; }
对于构造函数,您可以将其保留在标题中,尤其是在它为空的情况下,如您的示例所示:
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
}
答案 1 :(得分:0)
你需要在cpp中声明你定义的函数的作用域。
标题:
// 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
*/
Cpp:
#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;
}
并且请不要在头文件中使用 using namespace
,因为这可能会弄乱包含它们的任何人的代码。
请记住 #include <file>
是“在此处复制文件内容”