C++ 如何在基类中定义只在派生类中工作的方法?

C++ 如何在基类中定义只在派生类中工作的方法?,c++,inheritance,multiple-inheritance,C++,Inheritance,Multiple Inheritance,标题有点含糊不清,因此我将提供一个我想要实现的示例: class ValuePtr { public: operator const void*() { return glm::value_ptr(*this); // value ptr won't work on this class //(only works on glm types) } }; class Mat4x4: pu

标题有点含糊不清,因此我将提供一个我想要实现的示例:

class ValuePtr {
public:
    operator const void*() {
        return glm::value_ptr(*this); // value ptr won't work on this class 
                                      //(only works on glm types)
    }
};

class Mat4x4: public glm::mat4x4, public ValuePtr {
    // ...but would work here
};
class Vec3: public glm::vec3, public ValuePtr {
    // ...and here.
}
这样的事情在某种程度上可能发生吗

glm::value\u ptr
仅适用于
glm
类型,如
glm::mat4x4
glm::vec3
等。因此,如果我直接在派生类中实现上述方法,则该方法将有效,但它们都应以完全相同的方式定义
运算符const void*
。我想要一个类似于trait的行为:在公共基类中定义它,而该定义只在派生类中有效


感谢您的回答,这是我将使用的解决方案:

模板
类别估价师:公共T{
公众:
运算符常量void*(){
返回glm::value_ptr(*this);
}
};
Mat4x4类:公共估价师{
};

编辑:我想我现在根据其他评论/编辑理解了这个问题。我的下一个建议是尝试一个模板:

template<typename GlmType>
class ValuePtr {
private:
   const GlmType& m_glm;

public:
   ValuePtr(const GlmType& glm)
     :m_glm(glm)
   {
   }

   operator const void*() {
      return glm::value_ptr(m_glm);
   }
};

class Mat4x4: public glm::mat4x4, public ValuePtr<Mat4x4> {
public:
   Mat4x4()
      : ValuePtr(*this)
   {
   }
};
但是,也许您希望在两个类中都使用该函数,并在每种情况下执行不同的操作。我不知道您希望基础版本做什么,所以让它返回null:

class ValuePtr {
   operator const void*() {
      return nullptr;
   }    
};

class Mat4x4: public glm::mat4x4, public ValuePtr {
   operator const void*() {
      return glm::value_ptr(*this);
   }
};
最后,也许您将从ValuePtr派生多个类,并且所有这些类都需要可强制转换为const void*,但是没有合理的方法在基本身中实现这一点。在这种情况下,请使用纯虚拟函数:

class ValuePtr {
    virtual operator const void*() = 0;
};

class Mat4x4: public glm::mat4x4, public ValuePtr {
   virtual operator const void*() override {
      return glm::value_ptr(*this);
   }
};
(override关键字是可选的,实际上可能不起作用,这取决于您使用的编译器)。

您的意思是这样的吗

template<class GLM_THING> class has_value_ptr {
  has_value_ptr(const GLM_THING& data)
  : _glmData(data) { }
public:
  operator void*() {
    return &_glmData;
  }

  GLM_THING& glmData() { return _glmData; }
  const GLM_THING& glmData() const { return _glmData; }

private:    
  GLM_THING _glmData;
};

class Mat4x4 : public has_value_ptr<glm::mat4x4> {
public:
  Mat4x4(const glm::mat4x4& data)
  : has_value_ptr<glm::max4x4>(data)
  {
  }
  ...
};
模板类具有\u值\u ptr{
具有值(常量GLM和数据)
:_glmData(数据){}
公众:
运算符void*(){
返回&u glmData;
}
GLM_THING&glmData(){return_glmData;}
常量GLM_THING&glmData()常量{return_glmData;}
私人:
GLM_THING_glmData;
};
Mat4x4类:公共具有\u值\u ptr{
公众:
Mat4x4(常量glm::Mat4x4和数据)
:具有值(数据)
{
}
...
};

I,例如,我不明白你在问什么。可以使用move
operator const void*()
到Mat4x4,或者这个函数也需要存在于ValuePtr中吗?我编辑了这个问题,希望现在更清楚。@dlf我将有多个类似Mat4x4的类,所以我不想在所有这些类中定义它,但是这种方法应该是一个共同的特点。不要从
glm
类型派生。使用合成。这不是我想要的,我想要的是确切的定义
returnglm::value\u ptr(*this)
在许多类中,但我不想一次又一次地定义它。@AdamS所以多个类将从ValuePtr和glm:mat4x4派生,并且它们都需要这种行为?不是全部来自
glm::mat4x4
,而是来自不同的glm类型,例如
vec3
,所有这些都没有公共基类。请参阅再次更新的问题:如果glm::value_ptr不共享公共基础,它们如何工作?它只是有一堆重载吗?多亏了你的回答,我找到了一个稍微不同的解决方案!请参阅更新的问题。
class ValuePtr {
    virtual operator const void*() = 0;
};

class Mat4x4: public glm::mat4x4, public ValuePtr {
   virtual operator const void*() override {
      return glm::value_ptr(*this);
   }
};
template<class GLM_THING> class has_value_ptr {
  has_value_ptr(const GLM_THING& data)
  : _glmData(data) { }
public:
  operator void*() {
    return &_glmData;
  }

  GLM_THING& glmData() { return _glmData; }
  const GLM_THING& glmData() const { return _glmData; }

private:    
  GLM_THING _glmData;
};

class Mat4x4 : public has_value_ptr<glm::mat4x4> {
public:
  Mat4x4(const glm::mat4x4& data)
  : has_value_ptr<glm::max4x4>(data)
  {
  }
  ...
};