Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
Because method constness is part of the type signature for the method, and const/non-const methods are completely separate as far as the language is concerned. When you override a method in a deriv...
Answer
#2: Post edited
- Because method constness is part of the type signature for the method, and const/non-const methods are completely separate as far as the language is concerned. When you override a method in a derived class, the type signature must match _exactly_, otherwise you are not overriding at all.
- Consider that it is possible to have separate const and non-const methods on the same class, which can contain different code:
- ```
- class Foo {
- public:
- virtual void test() = 0;
- virtual void test() const = 0;
- };
- ```
- ```
- class FooDerived: public Foo {
- public:
- void test() override { std::cout << "Non-const\n"; }
- void test() const override { std::cout << "Const\n"; }
- }
- ```
- If the language allowed you to add const to a derived method, there would now be ambiguity over which base class method the `void test() const` derived method was overriding — is it overriding the base class const method, or just adding const to the base class non-const method? If the language were to try to resolve this with a rule like "You can add const to an overridden method only if the base class doesn't also define a const method of the same name", you would create the possibility that adding a const method to the base class would actually change _which_ method the derived class was overriding, which would be very surprising behaviour.
This is the same reason you can't override a method while changing the return type (e.g. from `float` to `double`). It may seem like a convenient and simple thing to do, but it violates the rule that an overriding method must match the type signature of the base method.
- Because method constness is part of the type signature for the method, and const/non-const methods are completely separate as far as the language is concerned. When you override a method in a derived class, the type signature must match _exactly_, otherwise you are not overriding at all.
- Consider that it is possible to have separate const and non-const methods on the same class, which can contain different code:
- ```
- class Foo {
- public:
- virtual void test() = 0;
- virtual void test() const = 0;
- };
- ```
- ```
- class FooDerived: public Foo {
- public:
- void test() override { std::cout << "Non-const\n"; }
- void test() const override { std::cout << "Const\n"; }
- }
- ```
- If the language allowed you to add const to a derived method, there would now be ambiguity over which base class method the `void test() const` derived method was overriding — is it overriding the base class const method, or just adding const to the base class non-const method? If the language were to try to resolve this with a rule like "You can add const to an overridden method only if the base class doesn't also define a const method of the same name", you would create the possibility that adding a const method to the base class would actually change _which_ method the derived class was overriding, which would be very surprising behaviour.
- This is the same reason you can't override a method while changing the return type (e.g. from `float` to `double`). It may seem like a convenient and simple thing to do, but it violates the rule that an overriding method must match the type signature of the base method.
- > Also, is there a good way to achieve this?
- It's not really clear what you want to achieve by changing the method constness, but here are some suggestions:
- * If you want the method to be const when called through the base class, add `const` to the signature on the base class.
- * If you want both const and non-const methods to be callable through the base class, you need to add _both_ signatures to the base class and override them separately.
- * If you can't, or don't want to, change the base class, but just want to call the method on const instances of the derived class, you can add a separate const method to the derived class (which won't be an override). However, this method will only be callable if you have an actual `FooDerived` reference or pointer, rather than a reference to the base class.
#1: Initial revision
Because method constness is part of the type signature for the method, and const/non-const methods are completely separate as far as the language is concerned. When you override a method in a derived class, the type signature must match _exactly_, otherwise you are not overriding at all. Consider that it is possible to have separate const and non-const methods on the same class, which can contain different code: ``` class Foo { public: virtual void test() = 0; virtual void test() const = 0; }; ``` ``` class FooDerived: public Foo { public: void test() override { std::cout << "Non-const\n"; } void test() const override { std::cout << "Const\n"; } } ``` If the language allowed you to add const to a derived method, there would now be ambiguity over which base class method the `void test() const` derived method was overriding — is it overriding the base class const method, or just adding const to the base class non-const method? If the language were to try to resolve this with a rule like "You can add const to an overridden method only if the base class doesn't also define a const method of the same name", you would create the possibility that adding a const method to the base class would actually change _which_ method the derived class was overriding, which would be very surprising behaviour. This is the same reason you can't override a method while changing the return type (e.g. from `float` to `double`). It may seem like a convenient and simple thing to do, but it violates the rule that an overriding method must match the type signature of the base method.