C++ 优雅地从嵌套类访问数据

C++ 优雅地从嵌套类访问数据,c++,class,oop,c++11,C++,Class,Oop,C++11,我有以下课程: 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";

我有以下课程:

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;
这个解决方案的问题是总是向我的实例传递一个指针是不舒服的


在这种情况下,如果在嵌套类中包含数据,同时保持调用像
a.ToString.DEC()
一样简单,那么解决方案是什么呢?

在某种程度上,您必须给
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;
};

不相关,但我建议只使用单独的
ToStringHex
ToStringDec
ToStringBin
函数。节省了不存储引用的时间,而且API通过这种方式更容易。

我看不到ToString结构中的任何基本原理

只需将这些方法留在BIGNUM中,就完成了


但是,对于这个特定的应用程序(在
ostream
中更改给定对象的渲染样式),我会让您的对象使用典型的
操作符进行打印。拥有代理对象的目的是什么(
ToString
)与其直接实现
BigNum
中的三个成员函数?@tedlynmo,我想将来重用它可能会更容易。只需将实例删除到该结构中,就可以更容易地禁用该选项。如果您现在看不到它有任何用处,您可以像这样推迟实现,直到需要该代理对象为止。很可能永远不会,它看起来有点像成语。这不一定是个坏主意。@Erlkoenig我看不出有什么相似之处。从方法返回
*这个
,它允许各种各样的好东西,比如链接,与这个代理对象几乎没有共同之处。
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;
};
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;   
}