C++ 类间转换

C++ 类间转换,c++,architecture,C++,Architecture,假设我们有一个叫做a的类和另一个叫做B的类。 我们想要一个转换方法,将a转换成B 从软件架构的角度来看,哪一个是首选的 写入A.export() 写入B.import() 编写一个转换器类,即convert(a,B)或convert(a)或 如果语言很重要,我使用的是C++这完全取决于您打算如何使用它,但在许多情况下,最干净的方法是实现转换构造函数: class B { }; class A { A(const B& b) { } }; B b; A a = b; //<

假设我们有一个叫做a的类和另一个叫做B的类。 我们想要一个转换方法,将a转换成B

从软件架构的角度来看,哪一个是首选的

  • 写入
    A.export()
  • 写入
    B.import()
  • 编写一个转换器类,即
    convert(a,B)
    convert(a)

  • 如果语言很重要,我使用的是C++

    这完全取决于您打算如何使用它,但在许多情况下,最干净的方法是实现转换构造函数:

    class B { };
    class A
    {
        A(const B& b) { }
    };
    
    B b;
    A a = b; //< calls converting constructor
    
    B类{};
    甲级
    {
    A(常数B&B){}
    };
    B B;
    A=b;//<调用转换构造函数
    

    (当然,您也可以实现一个转换构造函数,用于将
    a
    转换为
    B

    如果我们简单看一下Java(仅供参考,即使您使用的是C++):

    假设类A是字符串,类B是整数(或双精度、布尔值等c)。Java库设计者在Integer(“B”)中放置了一个名为getInteger(“导入”)的静态方法,该方法接受一个字符串(“a”)并生成一个整数(“B”)。那就是你的情况2

    另一方面,在每个类(称它们为“A”)中都有一个方法toString(“导出”),它返回一个字符串(“B”)。那就是你的情况1


    因此,即使对于这样的基本类,他们也决定使用不同的方法。我想这和@James McNellis所说的意思是一样的:这要看情况。

    首先,决定他们之间的转换是否真的是自然和直观的。在这种情况下,可以使用构造函数或成员函数

    但是,如果连接不是太自然,您可能希望使用一个单独的ConversionUtils类,使用转换方法或类似的方法。您不希望开始在类之间创建太多依赖项,或者最终实现n*n转换


    小心使用“转换构造函数”也很重要,因为它们可以在您没有意识到的情况下被调用。例如,如果我有一个
    a
    和一个
    b
    ,并且我写了类似
    a==b
    的东西,那么在a或b中存在一个构造函数,该构造函数取另一个构造函数,可能会导致编译成功而没有任何警告,并且在运行时可能会产生有趣的结果。在这些情况下,我强烈建议您使构造函数显式

    可以重载强制转换运算符,即运算符T(){..返回一个T值}。你是否应该是另一回事。

    我会使用你的第三个建议。用于转换的单独转换器类。这样,您就不会直接将A与B或B与A耦合。A和B将承担各自的责任


    C类转换器的职责纯粹是转换。每个班级只负责一件事,在我看来这是件好事。我相信这就是固体设计原则(单一责任原则)中的S

    作为补充,我建议将转换构造函数声明为显式A(constb&B)。然后,您将不得不使用
    A A=A(b)
    调用它,但当A
    b
    无意中转换为
    A
    时,您也将消除严重错误的风险。是的,我想这正是我需要的。谢谢again@Anders:这是真的,尽管我认为我从未遇到过由隐式转换引起的重大问题(C++/CLI除外,它不算;-P);我倾向于使用非显式构造函数进行转换,因为它通常使代码更简洁。如果构造函数是显式的,那么使用它通常比创建一个进行转换的非成员函数要复杂得多。如果我编写了一个非显式的转换构造函数,我会担心我会忘记它,并且在接下来的一两年会有一个严重的bug。是的,没错。我也得到了同样的观点。这完全是基于它们之间的内在联系。例如,在我的例子中,有两个对象存储一个顶点,一个用于核心内算法,另一个用于核心外操作。我认为在这种情况下,我最好编写显式转换。@尼玛:如果DiskVertex是顶点的一种可能表示形式,那么绝对不要更改顶点。你可能想让它成为一个带有构造函数的磁盘顶点,这个构造函数接受普通顶点,尽管我通常对此很小心。