是否可以使用一个父 class 的方法来实现另一个父 class 的抽象方法?
Is it possible to use a method from one parent class to implement an abstract method from another parent class?
我有以下 classes:
class ServoPart {
private:
bool move() {
/* move implementation for a singular servo */
}
}
struct RoboPart {
virtual void doJob() =0;
virtual bool move() =0;
}
class Claw : public ServoPart, RoboPart {
private:
void doJob() {/* implementation */}
}
class Arm : RoboPart {
private:
ServoPart major, minor;
void doJob() {/* implementation */}
bool move() {/* implementation for two servos */}
}
现在,Arm
可以工作了,因为它实现了 doJob
和 move
。然而 Claw
不起作用,因为它将是一个抽象的 class,因为它没有实现移动(即使它有来自基础 class 的 move
)。当我将 bool move() override;
添加到 Claw
时,我从链接器中得到了对 `vtable for Claw' 的未定义引用 失败。
有没有办法做到这一点?或者我是否需要将 ServoPart#move
重命名为 ServoPart#moveStep
并从 Claw 中的函数 move
调用它?
我试着摆弄了一下以了解 using
语句是否有用,但它似乎没有达到您的要求。
一种可能的解决方案是使用中介 class 并手动调用您想要的实现,如下所示:
#include <iostream>
class ServoPart {
public:
virtual bool move() {
std::cout << "servopart::move" << std::endl;
return true;
}
};
struct RoboPart {
virtual void doJob() =0;
virtual bool move() =0;
};
struct ServoRoboPart: public ServoPart, RoboPart
{
virtual bool move(){ ServoPart::move(); return true; };
};
class Claw : public ServoRoboPart {
public:
void doJob() {std::cout << "claw::doJob" << std::endl;}
};
class Arm : RoboPart {
public:
void doJob() {std::cout << "arm::doJob" << std::endl;}
bool move() {std::cout << "arm::move" << std::endl; return true;}
};
int main()
{
Claw c;
Arm a;
a.move();
a.doJob();
c.move();
c.doJob();
}
要使其正常工作,ServoRoboPart
必须能够看到 ServoPart::move
,因此至少必须 protected
。其他可见性更改是允许它在 ideone 上 运行:https://ideone.com/ar5OQl
输出是
arm::move
arm::doJob
servopart::move
claw::doJob
符合预期。
这里的主要问题是您的所有方法都是私有的,因此不能从定义 class 之外调用它们,甚至不能从子 class.
假设可以删除blocking private:
声明,使用superclass中的方法实现方法是没有问题的另一个超级class 提供它是可访问的,但实现必须是显式的:
class ServoPart {
protected:
bool move() {
/* move implementation for a singular servo */
}
};
class Claw : public ServoPart, RoboPart {
private:
void doJob() {/* implementation */}
bool move() {
return ServoPart::move();
}
};
}
如何创建另一个 Base class“零件”,然后从中继承 ServoPart 和 RoboPart
struct Part {
virtual bool move() = 0;
};
class ServoPart : public Part{
private:
bool move() {
/* move implementation for a singular servo */
}
};
struct RoboPart : public Part{
virtual void doJob() = 0;
};
class Claw : public ServoPart, RoboPart {
private:
void doJob() {/* implementation */}
bool move() {/* implementation */}
};
class Arm : RoboPart {
private:
ServoPart major, minor;
void doJob() {/* implementation */}
bool move() {/* implementation for two servos */}
};
我有以下 classes:
class ServoPart {
private:
bool move() {
/* move implementation for a singular servo */
}
}
struct RoboPart {
virtual void doJob() =0;
virtual bool move() =0;
}
class Claw : public ServoPart, RoboPart {
private:
void doJob() {/* implementation */}
}
class Arm : RoboPart {
private:
ServoPart major, minor;
void doJob() {/* implementation */}
bool move() {/* implementation for two servos */}
}
现在,Arm
可以工作了,因为它实现了 doJob
和 move
。然而 Claw
不起作用,因为它将是一个抽象的 class,因为它没有实现移动(即使它有来自基础 class 的 move
)。当我将 bool move() override;
添加到 Claw
时,我从链接器中得到了对 `vtable for Claw' 的未定义引用 失败。
有没有办法做到这一点?或者我是否需要将 ServoPart#move
重命名为 ServoPart#moveStep
并从 Claw 中的函数 move
调用它?
我试着摆弄了一下以了解 using
语句是否有用,但它似乎没有达到您的要求。
一种可能的解决方案是使用中介 class 并手动调用您想要的实现,如下所示:
#include <iostream>
class ServoPart {
public:
virtual bool move() {
std::cout << "servopart::move" << std::endl;
return true;
}
};
struct RoboPart {
virtual void doJob() =0;
virtual bool move() =0;
};
struct ServoRoboPart: public ServoPart, RoboPart
{
virtual bool move(){ ServoPart::move(); return true; };
};
class Claw : public ServoRoboPart {
public:
void doJob() {std::cout << "claw::doJob" << std::endl;}
};
class Arm : RoboPart {
public:
void doJob() {std::cout << "arm::doJob" << std::endl;}
bool move() {std::cout << "arm::move" << std::endl; return true;}
};
int main()
{
Claw c;
Arm a;
a.move();
a.doJob();
c.move();
c.doJob();
}
要使其正常工作,ServoRoboPart
必须能够看到 ServoPart::move
,因此至少必须 protected
。其他可见性更改是允许它在 ideone 上 运行:https://ideone.com/ar5OQl
输出是
arm::move
arm::doJob
servopart::move
claw::doJob
符合预期。
这里的主要问题是您的所有方法都是私有的,因此不能从定义 class 之外调用它们,甚至不能从子 class.
假设可以删除blocking private:
声明,使用superclass中的方法实现方法是没有问题的另一个超级class 提供它是可访问的,但实现必须是显式的:
class ServoPart {
protected:
bool move() {
/* move implementation for a singular servo */
}
};
class Claw : public ServoPart, RoboPart {
private:
void doJob() {/* implementation */}
bool move() {
return ServoPart::move();
}
};
}
如何创建另一个 Base class“零件”,然后从中继承 ServoPart 和 RoboPart
struct Part {
virtual bool move() = 0;
};
class ServoPart : public Part{
private:
bool move() {
/* move implementation for a singular servo */
}
};
struct RoboPart : public Part{
virtual void doJob() = 0;
};
class Claw : public ServoPart, RoboPart {
private:
void doJob() {/* implementation */}
bool move() {/* implementation */}
};
class Arm : RoboPart {
private:
ServoPart major, minor;
void doJob() {/* implementation */}
bool move() {/* implementation for two servos */}
};