【问题标题】:defining a public struct inside a class在类中定义公共结构
【发布时间】:2011-06-19 08:54:40
【问题描述】:

嘿,所以我正在制作一个函数来收集你想保留在屏幕上的精灵,并且
然后“检查()”它们以使它们停留在舒尔,否则使它们在屏幕边缘反弹。

我在我的类 ('Object') 中定义了一个结构,它持有对精灵的引用,以及它是否仍在屏幕之外。
(因此,reflect() 函数不是' t 在精灵真正回到屏幕内之前再次调用)

我对以下代码有三个问题:

  • 在我的 Object 结构中保存对 sprite 的引用是否允许我在调用 reflect() 时访问原始 sprite,而不仅仅是副本?

  • 为什么'Object'结构体用红色下划线表示Error: implicitly generated constructor for class "OnScreenCheck::Object" cannot initialize.

  • 在构造函数中,我创建了一个 Object 实例,并将其传递给 Objects 向量。我想,因为我将它传递给向量,所以向量会复制它并保存它,但我也想知道在构造函数完成后实例是否会被销毁,搞砸了。它会起作用吗?

感谢您的帮助!这是函子:

class OnScreenCheck
{
public:
    struct Object{
        mySprite& Sprite;
        bool OffScreen;};

    void AddObject(mySprite& aSprite){
        Object newObject;
        newObject.Sprite= aSprite;
        newObject.OffScreen= false;
        Objects.push_back(newObject);
    };

    void Check(){
                // make sure box1 stays on the screen
        for(int I=0; I< Objects.size(); I++){
            //sprite has gone to high or to low
            bool yColl (Objects[I].Sprite.Side(mySprite::top)>=ScreenHeight 
              || Objects[I].Sprite.Side(mySprite::bottom)<=0);
            //sprite has gone to far left or right
            bool xColl (Objects[I].Sprite.Side(mySprite::left)<=0 
              || Objects[I].Sprite.Side(mySprite::right)>ScreenWidth);

            if(Objects[I].OffScreen==false){
                if(yColl){
                    Objects[I].OffScreen= true;
                    Objects[I].Sprite.Reflect(180);}
                if(xColl){
                    Objects[I].OffScreen= true;
                    Objects[I].Sprite.Reflect(90);}
            }
        }
    };

编辑: 另外,我对 struct Object 的意图不是拥有属于 OnScreenCheck 的公共数据类型,而是使数据类型只能由 OnScreenCheck 使用,因为它保存了这些“对象”进入向量对象。它只是为了在 OnScreenCheck 中组织数据。我怎样才能做到这一点,这样我就不必立即在 OnScreenCheck 构造函数中初始化一个对象?

【问题讨论】:

    标签: c++ class constructor struct


    【解决方案1】:

    在我的 Object 结构中保存对 sprite 的引用是否允许我在调用 reflect() 时访问原始 sprite,而不仅仅是副本?

    引用需要在创建时进行初始化,并且它们仍然绑定到它们是别名的类型对象所以保存对sprite 的引用将始终指向同一个sprite 对象,任何尝试使它给别的东西取别名会导致错误。

    为什么 'Object' 结构用红色下划线表示Error: implicitly generated constructor for class "OnScreenCheck::Object" cannot initialize.

    您需要为OnScreenCheck 提供一个构造函数,它将适当地初始化Object 成员,尤其是sprite 的引用成员。该错误是因为引用必须在创建时初始化。

    在构造函数中,我创建了一个 Object 实例,并将其传递给 Objects 向量。我想,因为我将它传递给向量,所以向量会复制它并保存它,但我也想知道在构造函数完成后实例是否会被销毁,从而搞砸了。它会起作用吗?

    向量将保存对象的副本并且不会被销毁,除非您通过向量函数明确要求向量这样做,除非您的对象当然有一些指针类型。

    【讨论】:

    • 嘿,你能看看我在底部添加的新问题吗?谢谢!
    【解决方案2】:

    重新默认构造函数失败:

    struct Object{
        mySprite& Sprite;
        bool OffScreen;};
    

    默认构造时 - 您希望 Sprite 具有什么值?它是一个引用,它必须引用一个现有的对象,但默认情况下没有。这就是错误的原因。

    所以你可以这样做:

    class OnScreenCheck
    {
    public:
    struct Object{
        Object(mySprite& aSprite, bool screen) : Sprite(aSprite), OffScreen(screen) {};
        mySprite& Sprite;
        bool OffScreen;};
    
    void AddObject(mySprite& aSprite){
        Object newObject(aSprite, false);
        Objects.push_back(newObject);
    };
    

    加法

    重新添加到您的问题 - 答案很简单:将其定义为 privateprotected(以防您将来想使用继承)。这样 - OnScreenCheck 之外的任何代码都无法访问它。

    【讨论】:

    • 那么我为什么要设置默认参考?我认为这是不可能的。
    • @Griffin - 你不能,必须将引用初始化为现有对象,你不能使用默认构造函数来做到这一点。您可以改用指针(但要小心,使用智能指针,而不是通用指针)。
    • @Griffin - 您当然可以实现一个构造函数,该构造函数将接受一个引用作为参数并初始化该字段,并将其用作您的OnScreenCheck::AddObject 中的Object newObject(aSprite)
    • 嘿,你能看看我在底部添加的新问题吗?谢谢!
    【解决方案3】:

    只要原始对象保持活动状态(并且不会离开),该引用就有效。

    Object 不能默认构造,因为引用必须在创建时进行初始化。分配给引用并不会改变引用,而是改变它所引用的对象。

    在向量中存储副本并销毁原件似乎没问题。您可能只想要一个对象。

    【讨论】:

    • 嘿,你能看看我在底部添加的新问题吗?谢谢!
    • @Griffin - 如果您希望该结构仅在您的类中可用,您可以将其设为私有。这样其他人就无法使用它了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多