未在此作用域中声明实例化类/的作用域

scope of instantiated class / was not declared in this scope

本文关键字:作用域 实例化 声明      更新时间:2023-10-16

我是C++的新手,但我已经学会了一些Java,同时我也第一次使用SDL,但我的问题是我正在尝试创建一个对象(paddle)p1和p2。

这个

#ifndef PONG_H_
#define PONG_H_
#undef main
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>

class paddle{
private:
    int y;
    int yv;
    int x;
public:
    paddle(){
    y = 0;
    yv = 0;
    x = 0;
    }
    paddle(int ex, int why, int vel){
        y = why;
        yv = vel;
        x = ex;
        }
    void setY(int ycoord) {y = ycoord;}
    void setV(int velocity){ yv = velocity;}
    void setX(int xcoord) {x = xcoord;}
    int getX() {return x;}
    int getY() {return y;}
    int update(){y += yv; return y;}


};

class Pong { //pong class where everythin gets its name and a purpose.
private:
    SDL_Surface * Paddle;
    SDL_Surface * Ball; //SDL_Surface pointer for Ball
    SDL_Surface * screen;   //SDL_Surface  pointer to backbuffer
public:
    int Running;
    Pong(); //eh..
    int OnExecute(); //another function returning a value.
    int w; //width of screen
    int h; //height of screen
    bool OnInit();
    void OnEvent(SDL_Event* Event);
    void OnLoop();
    void OnRender();
    void OnCleanup();

    void redraw( int x, int y, SDL_Surface* source, SDL_Surface* destination ) { //Make a temporary rectangle to hold the offsets
    SDL_Rect offset; //Give the offsets to the rectangle
    offset.x = x; offset.y = y;
    SDL_BlitSurface( source, NULL, destination, &offset );//Blit the surface
    offset.x =0; offset.y=0; //resets the offsets sicne they apaprently dont reset per use.
    };
};

#endif /* PONG_H_ */

是我的头文件,它也包含pong类的主要函数,但我省略了这些函数,使事情不那么复杂。请告诉我是否需要这些才能得到一个好的答案。

我在这里声明对象。。。

#include <iostream>
#include <SDL/SDL.h>
#include "Pong.h"
paddle p1;
paddle p2;
Pong::Pong(){
h = 768;
w = 1024;
screen = NULL;
Paddle = NULL;
Ball = NULL;
Running = true;
atexit(SDL_Quit);
}
int Pong::OnExecute() {
    if(OnInit() == false)
        return-1;
    SDL_Event Event;
    while(Running) {
        while(SDL_PollEvent(&Event)) {
            OnEvent(&Event);
        }
        OnLoop();
        OnRender();
    }
    OnCleanup();
return 0;
}
int main( int argc, char* args[]) {
    Pong theApp;
    return theApp.OnExecute();
}

但让它变得困难的是我把它用在…这里:

#include "Pong.h"
void Pong::OnEvent(SDL_Event* Event) {
    if(Event->type == SDL_QUIT)
        Running = false;
    switch(Event->type)
    {
        case SDL_KEYDOWN: //look for key holds
            switch(Event->key.keysym.sym) //check key values and changes coords respectiely
            {
            default:
                break;
            case SDLK_UP:
                p2.setV(-2);
                break;
            case SDLK_DOWN:
                p2.setV(2);
                break;
            case SDLK_w:
                p1.setV(-2);
                break;
            case SDLK_s:
                p1.setV(2);
                break;
            case SDLK_ESCAPE:
            Running = false;
                break;
            }
            break;
        case SDL_KEYUP:
            switch(Event->key.keysym.sym)
            {
            default:
                break;
                case SDLK_UP:
                    p2.setV(0);
                    break;
                case SDLK_DOWN:
                    p2.setV(0);
                    break;
                case SDLK_w:
                    p1.setV(0);
                    break;
                case SDLK_s:
                    p1.setV(0);
                    break;
            }
            break;
        break;//break of Key holding event check
    }
}

我很难问这个问题,因为我不知道从哪里开始。我尝试了很多奇怪的事情,但现在我迷失了方向。如果你需要更多的信息,我很乐意提供。

void Pong::OnLoop(){
    if(p1.getY()<=0){
        p1.setV(0);
        p1.setY(0);
    }
    if(p2.getY()<=0){
        p2.setV(0);
        p2.setY(0);
    }
    if(p1.getY()>=h - Paddle->h){
        p1.setV(0);
            p1.setY(h - Paddle->h);
        }
    if(p2.getY()>=h - Paddle->h){
        p2.setV(0);
            p2.setY(h - Paddle->h);
        }
}

\src\Pong_OnLoop.cpp:11:5:错误:未在此作用域中声明"p1"

\src\Pong_OnLoop.cpp:15:5:错误:未在此作用域中声明"p2"

\src\Pong_OnLoop.cpp:19:5:错误:未在此作用域中声明"p1"

\src\Pong_OnLoop.cpp:23:5:错误:未在此作用域中声明"p2"

由于您还没有提供一个明确的问题,很难提供正确的答案,但我猜您无法在OnEvent-/OnLoop方法中访问p1和p2。

是否绝对有必要让这两个paddle对象位于全局名称空间中?因为在这种情况下,我认为最好有两个桨板成员作为Pong类的一部分,我也会使用这样的初始化列表:

class Pong {
private:
    SDL_Surface * Paddle;
    SDL_Surface * Ball; //SDL_Surface pointer for Ball
    SDL_Surface * screen;   //SDL_Surface  pointer to backbuffer
    paddle p1;
    paddle p2;
public:
    Pong() :
        h(768),
        w(1024),
        screen(NULL),
        Paddle(NULL),
        Ball(NULL),
        Running(true),
        p1(10, 384, 0),
        p2(1014, 384, 0) {
        atexit(SDL_Quit);
    };
    // ...
}; 

根据优化设置和默认内存初始化,您甚至可能不需要所有初始化程序,但这不是重点。这样,您就可以在Pongs自己的所有方法中访问p1和p2。Bo Perssons的回答可能也有效,但我认为这是一种更面向对象的方法,因此也是面向C++的方法。

附带说明:您说过头文件包含更多的方法——看到您的构造函数是在cpp文件中实现的,而重绘方法是在头文件中实现,您可能想了解更多关于内联的信息。在这个例子中,这不是什么大问题,但通常最好的做法是将更复杂的方法转移到翻译单元(cpp文件),尤其是在创建库时。

如果您希望桨板在定义它们的文件之外的其他文件中可见,则必须向头文件添加声明

extern paddle p1;
extern paddle p2;

这样其他.cpp文件就会知道它们的存在。