0

我正在尝试编写具有 4 个观点的应用程序。我想要一个场景对象,所有视口都引用了什么。我想做的是,如果场景对象发生变化,所有视点都会更新。这是我现在尝试实现它的方式:

#include <iostream>
#include <vector>

using namespace std;

class Scene
{
};

class Viewport
{
    public:
        Viewport( Scene &scene );
        void draw();

    private:
        Scene           *mScene;
};

Viewport::Viewport( Scene &scene )
{
    cout << mScene << endl;
    cout << &scene << endl;
    mScene = &scene;
    cout << mScene << endl;
    cout << &scene << endl << endl;
}

void Viewport::draw()
{
    cout << &mScene << endl;
}

int main( int argc, char *argv[] )
{
    Scene mScene;
    vector<Viewport> mViewPorts;

    mScene = Scene();

    cout << "init: " << endl;
    for( int i = 0; i < 4; i++ )
        mViewPorts.push_back( Viewport( mScene ) );

    cout << "main: " << endl;
    cout << &mScene << endl << endl;

    cout << "draw: " << endl;
    for( int i = 0; i < 4; i++ )
        mViewPorts[i].draw();
}

我的问题如下

1. 现在,第一个视口初始化一个空场景指针,地址为 CCCCCCCC。此获取已更新为主场景的地址。这就是我想要达到的目标。

CCCCCCCC <- mScene before
0016FBD3 <- &scene before
0016FBD3 <- mScene after
0016FBD3 <- &scene after

然而,其他观点已经开始于正确的地址,而不是 CCCCCCCC。为什么会这样?

对于视口 2、3、4,它看起来像这样:

0016FBD3
0016FBD3
0016FBD3
0016FBD3

2. 然而,我的主要问题是我的概念不起作用。当我调用 draw() 时,所有视口的地址都与我之前设置的地址完全不同。

draw:
00398730
00398734
00398738
0039873C

为什么会发生这些情况,解决上述问题的正确方法是什么

4

2 回答 2

1

您正在绘制中输出引用的地址。

您正在存储一个Scene*in mScene。然后,您将获取该指针的地址,该地址对于类的每个实例都是不同的。

我不知道另一个问题发生了什么。您是否可以尝试使用不同的场景实例初始化另一个视口,看看是否可行?

于 2012-12-07T13:35:23.833 回答
0
  1. 现在,第一个视口初始化一个空场景指针,地址为 CCCCCCCC。此获取已更新为主场景的地址。这就是我想要达到的目标。
CCCCCCCC <- mScene before
0016FBD3 <- &scene before
0016FBD3 <- mScene after
0016FBD3 <- &scene after

然而,其他观点已经开始于正确的地址,而不是 CCCCCCCC。为什么会这样?

您在为其分配值之前打印 mScene,因此无论在内存中存在什么垃圾值都会显示 - 显然它恰好是 CCCCCCCC,但是如果您在此处或那里稍微更改程序,或者更改编译器或优化级别,你可能会得到一个完全不同的值。您甚至可能在每次运行程序时得到不同的值,否则程序可能会崩溃。从尚未设置的变量中读取值是未定义的行为。简单地说,你的代码cout << mScene << endl;需要从 mScene 中读取来打印它,这在=赋值之后是可以的,但之前不行。

对于视口 2、3、4,它看起来像这样:

0016FBD3
0016FBD3
0016FBD3
0016FBD3

看起来是这样的,因为当您构造每个临时视口来推回它们时,它们几乎肯定是在程序堆栈中的同一位置构造的……最初 CCCCCCCC 的内存内容已被上一次该内存的值覆盖用于之前的 Viewport 对象,但由于读取的值没有重置为任何内容,因此您会看到来自早期 Viewport 的旧值。

  1. 然而,我的主要问题是我的概念不起作用。当我调用 draw() 时,所有视口的地址都与我之前设置的地址完全不同。
draw:
00398730
00398734
00398738
0039873C

为什么会发生这些,解决上述问题的正确方法是什么?

每个视口对象都包含一个指向场景的指针。您只有一个场景,但四个视口在显示的内存地址处有四个不同的指针,所有指针都包含单个场景的相同地址。

如果您打印 mScene 而不是 &mScene 您将看到您期望的值。

于 2012-12-07T13:51:14.420 回答