如何从构造函数作为参数的函数访问私有类的属性?

时间:2014-02-11 03:38:13

标签: c++

所以我有这个:

class Foo {
    public:
        Foo(void (*f)(Foo*));
    protected:
        int x;
};

void function(Foo *foo) {
    foo->x = 10;
}

int main () {
    Foo bar = Foo(&function);
}

理想情况下,我想通过'function'更改我想要的Foo实例的任何受保护属性。我不知道这样做的任何方法,因为我不能成为该函数的朋友,因为它只是作为参数传递给构造函数。

我可以通过保持相同的结构来实现这一点(我的意思是,通过在创建时使用外部函数来改变Foo的受保护元素)?

我正在编写游戏引擎,其想法是Foo是Room类,用户应该编写自己的函数来将资源加载到Room。所以,我不知道用户的功能名称是什么,因此我不能与它成为朋友。

3 个答案:

答案 0 :(得分:1)

1)将x声明为public。

2)在Foo中写一个setter函数来设置x。

3)声明作为朋友的功能,即friend void function(Foo*);

答案 1 :(得分:1)

简短的回答是,您无法向外部函数或类提供对受保护/私有类成员的访问权限,而无需明确授予他们“朋友”访问权。

我提出了一个仍然适合你当前方法/结构的替代方案:

class Room;

struct RoomAssets {
    int x;
    // ...
};

// Base class for loading Room assets
class AssetLoader {
public:
    virtual void loadAssets(RoomAssets *room) = 0;
};

class Room {

public:
    Room(AssetLoader *al) {
        RoomAssets ra;
        al->loadAssets(&ra);
        // do what ever you like with the struct values
        this->x = ra.x;
    }

protected:
    int x;
};

// A Room loader that loads 10 of each asset
class TenAssets : public AssetLoader {

public:
    void loadAssets(RoomAssets *ra) {
        ra->x = 10;
    }
};

int main() {
    TenAssets da;
    Room room(&da);
}

在此示例中,有一个Room类和一个AssetLoader类。 Room类调用了'{1}}方法,它传递了什么类型的'AssetLoader`。

loadAssets加载使用值传递的结构,AssetLoader对象可以随意使用值执行任何操作。

答案 2 :(得分:0)

您可能希望首先提供一个公共setX()函数,然后看看它是如何发生的。

除非绝对必要,否则你会希望避免公开x,例如出于性能原因,如果您在对代码进行分析后确定setX()函数正在减慢速度,那么您只需要执行此操作。

我不确定你能否在这种情况下成为朋友,而你可能也不想这样做。