【问题标题】:Given a class member, how can I access other members of the same class?给定一个班级成员,我如何访问同一班级的其他成员?
【发布时间】:2020-09-11 13:59:48
【问题描述】:

我有两个班级,我称它们为“foo”和“bar”。 “foo”有两个公共成员:(一个字符串作为它的名字和一个“bar”类型的向量)。

class bar {
    //not important
};

class foo {
public:
    std::string fooName;
    std::vector<bar> bars;
}

如果我有一个 bar 元素,我如何访问和打印其对应的 fooName?我正在考虑这些方面的事情,但我不知道如何填写空白:

std::cout << bars[index].__________.fooName;

当我尝试用谷歌搜索答案时,我只能找到有人询问有关访问其他类的私有成员的问题。

【问题讨论】:

  • 您确定不想要foos 的std::vector,其成员变量类型为bar?
  • 没有简单的方法可以做到这一点。除了将bars 直接存储在向量中,您还需要存储struct,而不是bar 包含指向foo 的指针。然后,您需要仔细更新这些指针,以确保它们在 foo 被移动或复制时保持有效。这很容易出错,因此如果可能,请考虑更改设计。
  • @IgorTandetnik 我正在尝试重新创建棋盘游戏。 foo 是一个大陆,bar 是大陆内的一个城市。董事会有多个大陆(foo),每个大陆都有多个城市(bar)。我希望能够打印大陆的名称,只要给出它所拥有的城市。
  • 您需要给每个bar 一个指向拥有它的foo 的指针。或者只是将大陆名称复制到每个城市。语言中没有内置神奇的反向指针;如果您需要一个,请在您的班级中添加一个。
  • @sharkie 帖子的标题与问题的内容不太匹配。您甚至没有封闭类的成员,而只有作为封闭类成员的向量的一个元素。这将潜在答案从“有时可能但丑陋且不可移植”更改为“如果不进行设计更改就不可能”。

标签: c++ class oop inheritance member


【解决方案1】:

所以我不完全确定这是否是您所追求的,但如果您的 foo 对象包含 bar 对象的集合,那么您应该知道要打印哪个 foo 对象名称。

struct Bar
{ std::string name; };

struct Foo
{
    Foo( std::string fooName ) 
        : name{ std::move( fooName ) } { }

    void AddBar( Bar bar ) 
    { bars.push_back( std::move( bar ) ); }

    bool Contains( std::string_view barName ) const
    {
        return ( std::find_if( std::begin( bars ), std::end( bars ), 
            [ &barName ]( const Bar& bar ) { 

                return bar.name.compare( barName ) == 0; 
            }) != std::end( bars ) );
    }

    std::string name;
    std::vector<Bar> bars;
};

int main( )
{
    Foo foo{ "North America" };
    foo.AddBar( { "New York" } );
    foo.AddBar( { "LA" } );
    foo.AddBar( { "Toronto" } );
    foo.AddBar( { "Seattle" } );
    foo.AddBar( { "BC" } );
    foo.AddBar( { "Winnipeg" } );

    // Check if a single foo instance contains the city.
    if ( foo.Contains( "Toronto" ) )
        std::cout << "City: Toronto Continent: " << foo.name << '\n'; 

    Foo foo2{ "South America" };
    foo2.AddBar( { "Lima" } );
    foo2.AddBar( { "Santiago" } );
    foo2.AddBar( { "Salvador" } );
    foo2.AddBar( { "Fortaleza" } );
    foo2.AddBar( { "Quito" } );

    std::vector<Foo> foos{ std::move( foo ), std::move( foo2 ) };

    // Check if any foo instance contains a specific city.
    const std::string cityName{ "Toronto" };

    auto it{ std::find_if( std::begin( foos ), std::end( foos ), 
        [ &cityName ]( const Foo& foo ) { return foo.Contains( cityName ); } ) };

    if ( it != std::end( foos ) )
        std::cout << "Continent: " << it->name << '\n';
}

【讨论】:

  • 感谢您的回复。有趣的是,与我的棋盘游戏中的城市相比,您使用的城市有多准确(如果您有兴趣,可以进行间谍追踪)。我最终做的事情,虽然可能不是很有效,但是做一个嵌套的 for 循环来扫描所有 foo 的 bars,直到找到匹配项,然后返回 foo。
  • if ( foo.Contains( "Toronto" ) ) 这只是按名称运行搜索。但是 OP 写了“如果我有 一个元素 of bar,”,我读到这意味着他们有一个bar 元素并想弄清楚它属于哪个foo。恕我直言,这与您的建议不同。例如,假设城市“伦敦”包含在欧洲和北美的列表中。它将具有相同的名称,但每个 foo 中的 bar 对象不同。如果你只有名字,你无法分辨它指的是哪一个,但是bar 对象唯一地属于一个foo 大陆。
  • @dxiv 老实说,我对 “如果我有条形元素” 有点困惑,所以我查看了他的 structure,然后猜到了。您对 London 示例的看法是正确的。您需要一些其他唯一标识符来确保您获得正确的London(如国家/地区)。必须更改 Contains 方法以搜索城市和国家或类似的东西。
  • @WBuck 或者,如果 OP 确实有(引用/指向)bar 对象,该对象已知位于 foo::bars 向量中,则可以简单地按地址进行匹配。不过,它仍然是线性搜索,而不是一些“神奇”的直接查找。
  • @dxiv 我怀疑(我再次猜测)他拥有的 bar 的单独集合不是 pointers/references 到他的 foo 中包含的 bar 对象. (这是一个奇怪的句子)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
  • 1970-01-01
  • 2022-01-10
  • 2021-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多