从课外访问联合“类型”?

时间:2015-07-10 22:43:33

标签: c++ struct unions

我有我编写的这段代码,所以我可以原子地将float和int一起编写为64位:

namespace X{

template<typename P>
class MyClass<P>{
    public:

        MyCompStruct getStruct(){
            return MyCompStruct;          // Is this correct?
        }

    private:

    float a;                                                

    struct MyCompStruct{
        union{
            struct{
                float                       b;                                                   
                int32_t                     c;                                              
            };

            uint64_t                        composite;
         };

         operator=(const MyCompStruct& src) {
              this->composite= src.composite; 
         }
    };
};

}

但我正在努力如何声明,以便我可以使用类型为MyClass

的ao对象从另一个类中获取结构:

X::MyClass<P>::MyCompStruct mcs = obj.getStruct();   // Completely wrong
mcs.b = ...
mcs.c = ...

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

您的代码有几个问题

  1. MyCompStruct是使用模板特化语法定义的。摆脱额外的<P>
  2. MyCompStruct被声明为private,因此只有MyClassMyClass的朋友才能访问它。如果您希望其他人访问MyCompStruct,您需要将其公开(如果您想限制对派生类的访问,则需要保护)。
  3. MyCompStructgetStruct首次使用后声明。在使用它之前声明它。
  4. 您的赋值运算符没有返回类型,也不返回任何数据。这是错误的。
  5. getStruct正在尝试返回类型而不是实例的类型。你需要在那里添加一些括号。
  6. 停止使用using namespace std;。这只是糟糕的形式。它不在你发布的代码中,但我能闻到它。
  7. getStruct似乎不是对对象进行任何修改的函数。宣布它const对你的灵魂有好处。
  8. 以下是您的代码,其中包含上述问题的所有修复程序。我删除了命名空间,因为它与此无关。

    template<typename P>
    class MyClass   //  Removed extra <P>
    {
    public: //  Make it public
    
        //  Decalre before it's usage.
        struct MyCompStruct
        {
            union{
                struct{
                    float                       b;
                    int32_t                     c;
                };  //  Unnamed unions are a non-standard. Be careful.
    
                uint64_t                        composite;
            };
    
            //  Added a return type
            MyCompStruct& operator = (const MyCompStruct& src)
            {
                composite = src.composite;
    
                //  Returning this allows operations to be chained a = x = y;
                return *this;
            }
        };
    
    
        MyCompStruct getStruct() const
        {
            return MyCompStruct();  //  Return an instance instead of a type
        }
    
    private:
    
        float a;
    };
    

    基本用法:

    int main()
    {
        MyClass<int> obj;
        MyClass<int>::MyCompStruct mcs = obj.getStruct();
    }
    

    现在所有这些都已修复,您可以选择getStruct

    在上面的版本中,它返回一个新创建的MyCompStruct实例。如果你想要/需要的只是访问类型本身而且所有getStruct都是创建一个空实例你可以完全摆脱getStruct并允许其他人直接创建MyCompStruct的实例

    int main()
    {
        MyClass<int>::MyCompStruct mcs;
    }
    

    如果这不是你想要的行为,你宁愿通过MyClass返回一个已经创建的实例(作为成员变量)的引用或指针,你可以像下面那样改变它

    template<typename P>
    class MyClass
    {
    public:
    
        /**** Removed unchanged code ****/
    
        // Return a non-const reference allowing others to modify the
        // contents of compData. If you don't want others to MODIFY the data
        // change the return type to const MyCompStruct&
        MyCompStruct& getStruct()
        {
            return compData;  //  Return our owned instance
        }
    
        // Return a const reference to compData. This prevents others
        // from modifying the data and allows them to access it with a
        // const qualified instance of MyClass.
        const MyCompStruct& getStruct() const
        {
            return compData;  //  Return our owned instance
        }
    
    private:
    
        MyCompStruct compData;
    };