C++ 如何访问私有类';来自构造函数作为参数的函数的属性?

C++ 如何访问私有类';来自构造函数作为参数的函数的属性?,c++,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实例的任何受保护属性。我不知道有什么方法可以做到

所以我有这个:

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中。因此,我不知道用户函数名是什么,因此我无法与它成为朋友。

1)将x声明为公共

2) 在Foo中编写设置x的setter函数


3) 将函数声明为友元,即友元无效函数(Foo*)

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

除非绝对必要,否则您将希望避免将x公开,例如出于性能原因,并且只有在分析代码后确定setX()函数正在减慢速度时,才希望这样做


我不确定在这种情况下您是否能够成为好友,而且您可能无论如何都不想这样做。

简短的回答是,如果不明确地授予受保护/私有类成员“好友”访问权限,您就无法授予他们对外部函数或类的访问权限

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

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);
}
在本例中,有一个房间类和一个
AssetLoader
类。Room类调用传递给它的任何类型的“AssetLoader”的
loadAssets
方法


AssetLoader
加载传递值的结构,并且
Room
对象可以自由地对值执行任何操作。

阅读“友元函数”是的,我知道我可以在Foo类中与“函数”交朋友,但我正在编写一个游戏引擎,其思想是Foo是一个Room类,用户应该编写自己的函数来将资源加载到Room中。所以,我不知道用户函数名是什么,所以我不能和它交朋友。你可以通过名字和函数交朋友。与您成为朋友的函数将成为界面的一部分。不能通过指针与函数交朋友。这意味着你的界面是无限的,任何函数都可以选择成为它的一部分。这就等于把所有的事情都公开了,因为你无法控制谁能做得很好。为什么绕过C++成员访问规则?几乎可以肯定的是,你应该重新评估你的设计。公开不是违背了目的吗?我不想公开x,但我想我会采用公开setter函数的方法。不知道我以前怎么没看到。。。是的,我知道我的设计非常复杂,它可能会做得更好,但目前还可以。谢谢谢谢我想我会采用这种方法。性能暂时不是一个大问题,因为我只是为简单的游戏编写一个2D游戏引擎,但无论如何我会记住这一点。