编译器:“实例化对象”没有命名类型

Posted

技术标签:

【中文标题】编译器:“实例化对象”没有命名类型【英文标题】:Compiler: "instantiated object" does not name a type 【发布时间】:2014-11-07 15:17:01 【问题描述】:

我在使用 C++ 创建 WIN32 GUI 应用程序时遇到问题(我使用 Code::Blocks 自动生成 main.cpp)。这是我为将对象绘制到屏幕上的类制作的头文件。

#ifndef CANVAS_H
#define CANVAS_H
#include <windows.h>

class Point
private:
    const double default_x = 0.0, default_y = 0.0;
public:
    double x, y;
    Point();
    Point(const Point& rval);
    Point(double x, double y);
    bool operator==(const Point& rval);
    Point& operator=(const Point& rval);
    Point distanceAway(double x, double y);
;

class GraphicObject
private:
    int size;
    Point offset;
    Point* points;
public:
    GraphicObject();
    GraphicObject(const GraphicObject& rval);
    void paint(HWND& hwnd, HDC hdc);
    void addPoint(const Point& p);
    //void removePoint(const Point& p);
;
#endif

下面是实现:

#include "Canvas.h"
#include <windows.h>

//Point Class Definitions
//Default constructor
Point::Point(): x(default_x), y(default_y)
//Copy constructor
Point::Point(const Point& rval): x(rval.x), y(rval.y)
//Constructor
Point::Point(double x, double y): x(x), y(y)
//Equality operator
bool Point::operator==(const Point& rval) return (x == rval.x && y == rval.y); 
//Assignment operator
Point& Point::operator=(const Point& rval)
x = rval.x;
y = rval.y;
return *this;

//Function to find point certain distance away from calling object
Point Point::distanceAway(double x, double y) return Point(this->x + x, this->y + y); 

//GraphicObject Class Definitions
//Default constructor (makes a triangle)
GraphicObject::GraphicObject()
points = new Point[(size = 0)];
offset = Point(50,50);

//Copy constructor
GraphicObject::GraphicObject(const GraphicObject& rval)
delete[] points;
points = new Point[(size = rval.size)];
for(int i=0; i<size; i++) points[i] = rval.points[i]; 

//Function to paint to screen
void GraphicObject::paint(HWND& hwnd, HDC hdc)
hdc = GetDC(hwnd);
for(int i=0; i<(size - 1); i++)
    MoveToEx(hdc, points[i].x + offset.x, points[i].y + offset.y, NULL);
    LineTo(hdc, points[i + 1].x + offset.x, points[i + 1].y + offset.y);

MoveToEx(hdc, points[size - 1].x + offset.x, points[size - 1].y + offset.y, NULL);
LineTo(hdc, points[0].x + offset.x, points[0].y + offset.y);

ReleaseDC(hwnd, hdc);

//Function to add points to shape
void GraphicObject::addPoint(const Point& p)
Point* temp = new Point[size];//DYNAMIC MEMORY temp ALLOCATED
for(int i=0; i<size; i++)
    temp[i] = points[i];

delete[] points;
points = new Point[++size];
for(int i=0; i<(size - 1); i++) points[i] = temp[i]; 
delete[] temp;//DYNAMIC MEMORY temp DELETED
points[size - 1] = p;

在 main.cpp 中,当我实例化类 GraphicObject 的对象后,编译器在该行发现错误。

#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif

#include <tchar.h>
#include <windows.h>
#include <iostream>
#include <chrono>
#include <thread>
#include "Canvas.h"

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

int WINAPI WinMain (HINSTANCE hThisInstance,
                 HINSTANCE hPrevInstance,
                 LPSTR lpszArgument,
                 int nCmdShow)

HWND hwnd;               /* This is the handle for our window */
MSG messages;            /* Here messages to the application are saved */
WNDCLASSEX wincl;        /* Data structure for the windowclass */

/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);

/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;                 /* No menu */
wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
wincl.cbWndExtra = 0;                      /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
    return 0;

/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
       0,                   /* Extended possibilites for variation */
       szClassName,         /* Classname */
       _T("Code::Blocks Template Windows App"),       /* Title Text */
       WS_OVERLAPPEDWINDOW, /* default window */
       CW_USEDEFAULT,       /* Windows decides the position */
       CW_USEDEFAULT,       /* where the window ends up on the screen */
       544,                 /* The programs width */
       375,                 /* and height in pixels */
       HWND_DESKTOP,        /* The window is a child-window to desktop */
       NULL,                /* No menu */
       hThisInstance,       /* Program Instance handler */
       NULL                 /* No Window Creation data */
       );

/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);

/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))

    /* Translate virtual-key messages into character messages */
    TranslateMessage(&messages);
    /* Send message to WindowProcedure */
    DispatchMessage(&messages);


/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;


int x = 0, y = 10;
GraphicObject g;
g.addPoint(Point());

/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

PAINTSTRUCT ps;
HDC hdc;
switch (message)                  /* handle the messages */

    case WM_PAINT:
        //x++;
        //hdc = BeginPaint(hwnd, &ps);
        //hdc = GetDC(hwnd);
        //Rectangle(hdc, 0, 0, 544, 375);
        //TextOut(hdc, x, y, "MOVING TEXT WOO!", strlen("MOVING TEXT WOO!"));
        //ReleaseDC(hwnd, hdc);
        //EndPaint(hwnd, &ps);
        g.paint(hwnd, hdc);
        std::cout << "Window repainted\n";
        Sleep(5);
        break;
    case WM_DESTROY:
        PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
        break;
    default:                      /* for messages that we don't deal with */
        return DefWindowProc (hwnd, message, wParam, lParam);
        InvalidateRect(hwnd, NULL, true);
        UpdateWindow(hwnd);

return 0;

具体来说,这一行是我遇到问题的地方:

g.addPoint(Point());

【问题讨论】:

这段代码是巨大的。你的测试用例在哪里? 如果你正确缩进你的代码,你会很容易看出问题出在哪里。 【参考方案1】:

您正在尝试使用不是命名空间范围内的声明的语句。这是禁止的:声明语句以外的语句只能出现在函数体中。

要在命名空间范围内对对象应用操作而不是在函数中,即在初始化期间,您可以利用辅助对象的构造函数,例如:

GraphicObject g;
namespace 
    struct g_init 
        g_init()  g.addPoint(Point()); 
     init;

如果 GraphicObject 类型是可复制/可移动的,那么使用函数调用来初始化对象可能会更容易:

namespace 
    GraphicObject g_init() 
        GraphicObject g;
        g.addPoint(Point());
    

GraphicObject g = g_init();

【讨论】:

以上是关于编译器:“实例化对象”没有命名类型的主要内容,如果未能解决你的问题,请参考以下文章

c#为啥实例化对象?啥情况下实例化对象?

c++实例化一个对象

实例化对象时编译错误

C# 如何根据指定变量来实例化对象?

PHP面相对象:声明类和实例化类

js用new实例化对象与直接调用的this的区别