gpt4 book ai didi

c++ - 当变量恰好是指针时,如何在非成员函数中使用私有(private)成员变量?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:29:31 25 4
gpt4 key购买 nike

本质上,我的问题是我正在使用的库中的一个函数(此代码中的函数 Foo)需要一个指向对象 (Object* mbar) 的指针作为参数。但是,mbar 是 bar 的私有(private)成员变量。

通常,我只使用 getter 并按值传递,但如果我传递指针,这将提供对资源的直接访问,这会破坏封装。任何代码都可以调用 getter 并自由修改它。

接下来我想到的是我可以使用 const 指针,因为它们不允许修改它们指向的资源,但据我所知,我需要修改 Foo 才能接受它,这是不可能的,因为它是库函数。

我能想到的最后一件事就是简单地使用 Bar 的友元来调用 FoobarFunction,但我一直被告知友元函数是最后的手段。

有没有办法在不破坏封装的情况下做到这一点?

//Main.cpp

#include "Foobar.h"

int main()
{
Foobar fb;
Bar b;
fb.FoobarFunction(b);
return 0;
}

//Bar.h

#include "Object.h"

class Bar
{
private:
Object* mbar;
};

//Foobar.h

#include "Foo.h"
#include "Bar.h"

class Foobar
{
public:
void FoobarFunction(Bar bar)
{
Foo(bar.mbar);
}
};

最佳答案

简单的出路

你可以将指针设为const,然后在将它传递给库函数时进行转换

Foo(const_cast<Object *>(bar.mbar));

如果 Foo 不尝试修改 mbar,这将起作用。类型转换删除了“仅在名称上”的常量。尝试修改 secret 常量值可能会导致可怕的事情。

但是真的...

即使有办法让 Bar 返回一个“只读”指针,你问题中的代码示例仍然会违反封装。这种特殊的非封装风格称为 feature envy :数据存在于一个对象中,但另一个对象正在执行大部分数据操作。一种更面向对象的方法是将操作和数据移动到同一个对象中。

显然,您提供给我们的示例代码比您的实际项目要简单得多,所以我不知道重构您的代码的最明智的方法。这里有一些建议:

  1. 将 FoobarFunction 移到 Bar 中:

    class Bar
    {
    private:
    Object* mbar;
    public:
    void FoobarFunction()
    {
    Foo(mbar);
    }
    };
  2. 使用 dependency injection .在创建 Bar 之前初始化 mbar,然后将 mbar 传递给 Bar 的构造函数。

    int main()
    {
    Object *mbar;
    Foobar fb;
    Bar b(mbar);
    fb.FoobarFunction(mbar);
    return 0;
    }

    在此示例中,Bar 不再是 mbar 的“所有者”。 main方法直接创建mbar,然后传给需要的人。

    乍一看,这个例子似乎打破了我之前提到的准则(数据和行为存储在不同的对象中)。但是,上述与在 Bar 上创建 getter 有很大区别。如果 Bar 有一个 getMBar() 方法,那么世界上任何人都可以过来获取 mbar 并将其用于他们想要的任何邪恶目的。但在上面的示例中,mbar (main) 的所有者可以完全控制何时将其数据提供给另一个对象/函数。

除了 C++ 之外,大多数面向对象的语言都没有“友元”结构。根据我自己的经验,依赖注入(inject)是解决许多 friend 旨在解决的问题的更好方法。

关于c++ - 当变量恰好是指针时,如何在非成员函数中使用私有(private)成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23320487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com