I have a base class and many derived classes, defined in the following way:
class BaseClass {
public:
virtual ClassType getClassType() {return classType;}
private:
ClassType classType = BaseType;
}
class DerivedClass: public BaseClass {
public:
ClassType getClassType() override {return classType;}
private:
ClassType classType = DerivedType;
}
There are many similar derived classes of the same base class that share a similar structure.
I have a generator that keeps generating BaseClass
objects, and each time I will call x.getClassType()
to know its class type, then use dynamic_cast
to cast it to the corresponding derived class.
The problem is, I have to write the same getClassType()
function over and over again in each of the derived classes.
Is there anyway to just write the function only once, and each class will return their corresponding value of classType
when called from a BaseClass*
?
CodePudding user response:
I will call
x.getClassType()
to know its class type, then usedynamic_cast
to cast it to the corresponding derived class.
If you know what an object's type is, you can use static_cast
instead of dynamic_cast
. On the other hand, if you use dynamic_cast
, you can get rid of getClassType()
altogether, as you can just query the object whether it matches a given type.
Is there anyway to just write the function only once, and each class will return their corresponding value of
classType
when called from aBaseClass*
?
You only need one classType
member, in the BaseClass
, you don't need to repeat that member for each class. As such, you can remove virtual
from getClassType()
, and then give BaseClass
a constructor parameter to assign the classType
member. That way, DerivedClass
can then pass its type to the BaseClass
constructor, eg:
class BaseClass {
public:
BaseClass(ClassType classType = BaseType) : classType(classType) {}
ClassType getClassType() { return classType; }
private:
ClassType classType;
};
class DerivedClass : public BaseClass {
public:
DerivedClass() : BaseClass(DerivedType) {}
};
The downside to this approach is if you want to derive another class from DerivedClass
later on, you will have to give DerivedClass
a similar constructor to passed along the new class's type, eg:
class BaseClass {
public:
BaseClass(ClassType classType = BaseType) : classType(classType) {}
ClassType getClassType() { return classType; }
private:
ClassType classType;
};
class DerivedClass : public BaseClass {
public:
BaseClass(ClassType classType = DerivedType) : classType(classType) {}
};
class AnotherClass : public DerivedClass {
public:
AnotherClass() : DerivedClass(AnotherType) {}
};
Otherwise, you can leave virtual
on getClassType()
, and get rid of the classType
member altogether. Simply have BaseClass
and DerivedClass
(and any subsequent classes) override getClassType()
to directly return their respective type, eg:
class BaseClass {
public:
virtual ClassType getClassType() { return BaseType; }
};
class DerivedClass : public BaseClass {
public:
ClassType getClassType() override { return DerivedType; }
};
class AnotherClass : public DerivedClass {
public:
ClassType getClassType() override { return AnotherType; }
};