【问题标题】:How to return struct from class where it is defined?如何从定义它的类返回结构?
【发布时间】:2022-01-12 18:06:43
【问题描述】:

我想从公共类函数返回一个结构的副本,我在这个类中定义这个结构作为一个私有成员。

是否可以返回任何其他类型的自定义数据的这种结构?

考虑这个简单的例子:

class Test {
private:
    struct sTest {
        int i = 1;
    }_sTest;
public:
    sTest GetStruct() {
        return _sTest;
    }
};

然后在我创建这个类的对象之后:

Test cTest;

我怎么打电话

 cTest.GetStruct()

得到

 _sTest

?

【问题讨论】:

  • 问题是调用GetStruct()的用户无权访问私有成员,也不知道结构的实现。
  • 如果名称 sTest 是私有的,您如何期望调用代码现在知道如何处理 GetStruct 返回的 sTest?从技术上讲,您可以执行 auto something = sTest.GetStruct(); 之类的操作,因为只有 name sTest 是私有的 (demo here),但是……您为什么要这样做?如果sTest 应该对调用代码有意义,请将其作为类的公共接口的一部分。
  • 如果我将 sTest 公开,那么它将不会被封装。我要做的就是读取存储在类内部私有结构中的数据。有更好的方法吗?
  • 我也有从 cTest 派生的子类,它们重载 GetStruct() 并有自己的 sTest 结构实现,所以我需要为每个子类设置 sTest 唯一
  • 如果您在公共函数中返回 sTest 并且您希望调用代码能够直接在 sTest 上操作,那么您已经没有“封装”任何东西,因为这些实现细节需要知道。或许找出存储在sTest 中的特定数据需要向该类的用户公开并编写返回该数据的函数?

标签: c++ c++11


【解决方案1】:

您可以使用auto 来存储对象。

以下是示例代码。 See it here in action:

#include <iostream>
using namespace std;

class Test {
private:
    struct sTest {
        int i = 1;
    }_sTest;
public:
    sTest GetStruct() {
        return _sTest;
    }
};



int main()
{
    Test a;
    auto obj = a.GetStruct();
    
    cout<< obj.i <<"\nDone!!!\n";
    return 0;
}

输出:

1
Done!!!

注意:在其他编译器上也可以。也检查here on other compilers

【讨论】:

  • 谢谢,是的,我已经想出了这个解决方法,但我怀疑这是否安全。
  • @hgrev 我检查了coliru.stacked-crooked.com 上可用的编译器,看起来还不错。没有编译器抱怨。
【解决方案2】:

以防万一你不想在你的类中声明你的结构:

// not necessarily a member function
auto GetStruct()
{
  struct sTest {
        int i = 1;
    };
  return sTest();
}

using test_t = decltype(GetStruct()); // you can make an alias for an anonymous struct.
auto test = GetStruct();

【讨论】:

  • 谢谢,有趣!
【解决方案3】:

由于无法从外部类Test访问私有类,所以使用关键字auto

auto test = cTest.GetStruct();

【讨论】:

    【解决方案4】:

    是的,它非常安全。它与任何其他类型的数据一样。使用 auto 你只是告诉编译器猜测哪种变量会是。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多