优雅地访问嵌套类中的数据

Posted

技术标签:

【中文标题】优雅地访问嵌套类中的数据【英文标题】:Accessing data from a nested class elegantly 【发布时间】:2019-10-11 10:01:40 【问题描述】:

我有以下课程:

class BigNum

public:
    BigNum(string StrNumber) : Number(std::move(StrNumber)) 
    BigNum(const char *StrNumber) : Number(string(StrNumber)) 
    ~BigNum() = default;

    struct
    
        string HEX()  return Number + " - HEX"; 
        string DEC()  return Number + " - DEC"; 
        string BIN()  return Number + " - BIN"; 
    ToString;

private:
    string Number;
;

最后,我希望通过以下方式优雅地访问该结构中的函数:

BigNum a = "1234";
cout << "a = " << a.ToString.DEC() << endl;
cout << "b = " << a.ToString.HEX() << endl;

这里的问题是我无法从我的结构中访问变量Number

我知道这样的事情可以解决我的问题:

struct

    string HEX(BigNum &parent)  return parent.Number + " - HEX"; 
...
ToString;

这个解决方案的问题是总是将指针传递给我的实例是不舒服的。

在这种情况下,将数据保存在嵌套类中并同时保持调用像 a.ToString.DEC() 这样简单的解决方案是什么?

【问题讨论】:

拥有代理对象(ToString)而不是直接实现BigNum中的三个成员函数的目的是什么? @TedLyngmo 我在想,将来重用它可能会更容易。并且通过仅将实例删除到该结构来更容易禁用该选项。 如果您现在看不到它有任何用处,您可以像这样推迟实现它,直到出现对该代理对象的需求。很有可能它永远不会。 它看起来有点像named parameter 成语。不一定是个坏主意。 @Erlkoenig 我没有看到相似之处。从方法中返回*this,它允许各种好东西,比如链接,与这个代理对象几乎没有共同之处。 【参考方案1】:

在某种程度上,您必须给ToString 一个引用或指向BigNum 对象的指针,这样您才能访问Number。像这样的东西怎么样:

class BigNum

public:
    BigNum(string StrNumber) : Number(std::move(StrNumber)) 
    BigNum(const char* StrNumber) : Number(string(StrNumber)) 
    ~BigNum() = default;

    // you can make the struct private so the type is not visible externally
    struct ToStringType
    
    private:
        const BigNum& ref;

    public:
        ToStringType(const BigNum& r) : ref(r) 

        string HEX()  return ref.Number + " - HEX"; 
        string DEC()  return ref.Number + " - DEC"; 
        string BIN()  return ref.Number + " - BIN"; 
    ;

    ToStringType ToString *this ;

private:
    string Number;
;

无关紧要,但我建议简单地使用单独的 ToStringHexToStringDecToStringBin 函数。节省了不存储引用,而且 API 更容易这种方式。

【讨论】:

【参考方案2】:

我在 ToString 结构中看不到任何理由。

只需将方法保留在 BIGNUM 中即可。

但是,对于这个特定的应用程序(在 ostream 中更改给定对象的渲染样式),我会让您的对象使用典型的 operator&lt;&lt; 重载打印,然后使用 io-manipulators 修改渲染样式,以便您能够:

cout << "a (DEC) = " << BigNum::DEC << a << endl;
cout << "a (HEX) = " << BigNum::HEX << a << endl;

一个完整的例子:

#include <iostream>
#include <iomanip>

using namespace std;

class BigNum

public:
    BigNum(string StrNumber) : Number(std::move(StrNumber)) 
    BigNum(const char *StrNumber) : Number(string(StrNumber)) 
    ~BigNum() = default;

    static std::ios_base& DEC(std::ios_base& os) 
        os.iword(rendering_style_xalloc) = 0;
        return os;
    

    static std::ios_base& HEX(std::ios_base& os) 
        os.iword(rendering_style_xalloc) = 1;
        return os;
    

    static std::ios_base& BIN(std::ios_base& os) 
        os.iword(rendering_style_xalloc) = 2;
        return os;
    
private:
    static int rendering_style_xalloc;
    string Number;

    friend ostream &operator << (ostream &ostr, const BigNum &bignum);
;

int BigNum::rendering_style_xalloc = std::ios_base::xalloc();

ostream &operator << (ostream &os, const BigNum &bignum) 
    switch (os.iword(BigNum::rendering_style_xalloc)) 
        case 0:
            os << bignum.Number << " - DEC";
            break;
        case 1:
            os << bignum.Number << " - HEX";
            break;
        case 2:
            os << bignum.Number << " - BIN";
            break;
        default:
            os << bignum.Number << " - UNK";
            break;
    
    return os;
 

int main(int argc, char **argv)

    BigNum a = "1234";
    cout << BigNum::DEC << "a (DEC) = " << a << endl;
    cout << BigNum::HEX << "a (HEX) = " << a << endl;   

参考资料: https://en.cppreference.com/w/cpp/io/ios_base/iword

【讨论】:

以上是关于优雅地访问嵌套类中的数据的主要内容,如果未能解决你的问题,请参考以下文章

Java中私有静态嵌套类中的访问修饰符

嵌套类:如何访问封闭类中的成员变量

动态实例化嵌套在抽象类中的内部类

如何访问嵌套类的私有成员?

Java核心基础知识——Java 中的嵌套类

Java核心基础知识——Java 中的嵌套类