In one of our text-books it is suggested that we should use interfaces in C++ as a good design practice. They give below example;
class IAnimation
{
public:
virtual void VAdvance(const int deltaMilisec) = 0;
virtual bool const VAtEnd() const = 0;
virtual int const VGetPostition() const = 0;
};
I did not get the meaning of:
virtual bool const VAtEnd() const = 0;
virtual int const VGetPostition() const = 0;
I know const is used after () to make them invocable from const instances. But what const before VAtEnd and VGetPosition (method names) mean?
Thank you.
It means the return type is const, it's the same as:
virtual const bool VAtEnd() const = 0;
virtual const int VGetPostition() const = 0;
It has no practical meaning though, as the return value is copied anyway.
If you'd be returning an object though:
struct A
{
void goo() {}
};
const A foo() {return A();}
int main()
{
A x = foo();
x.goo(); //ok
foo().goo(); //error
}
Related
I wanted to understand how the inline member variable work while accessing it through a const member variable.
Each time I try doing so, I get an error!
This is what I am trying
#include <iostream>
#include <string>
using namespace std;
class A{
public:
A()
{
_uuid = 0;
}
~A();
void setUUID(int n) { _uuid = n; }
inline int getUUID(){ return _uuid;} const
int getUUID1() const { return _uuid;}
int getUUIDsmart()const
{
return _uuid;
}
private:
int _uuid;
};
class B {
public:
B(){}
~B();
void fun1(const A *obj)
{
cout<<obj->getUUIDsmart()<<endl; //works fine
cout<<obj->getUUID1()<<endl; //works fine
cout<<obj->getUUID()<<endl; //error
A *obj1 = const_cast<A *>(obj);
cout<<obj1->getUUID()<<endl; //works fine
}
};
int main()
{
B *b = new B;
A *a = new A;
a->setUUID(12);
b->fun1(a);
}
I am able to get my code work through
const_cast
But I am interested in knowing why do i get an error in the inline function if I try accessing it through a const member function?
Update: FIX
My bad. I had the placement of const messed up!
Thanks to #bruno
inline int getUUID() const { return _uuid; }
//correct syntax. i placed the const at the end
[note : I use the first version of the question]
you place wrongly your const :
inline int getUUID(){ return _uuid;} const
int getUUID1(){ return _uuid;} const
int getUUIDsmart()const
is in fact
inline int getUUID(){ return _uuid;}
const int getUUID1(){ return _uuid;}
const int getUUIDsmart()const
I just moved the const on the right line for readability reason
You wanted
inline int getUUID() const { return _uuid;}
int getUUID1() const{ return _uuid;}
in your version none of getUUID1 nor getUUID are const so you cannot apply them on a const instance
There is no link at all with the fact your methods are inline or not.
Note :
cout<<obj->getUUID1()<<endl; //works fine
it doesn't
I would like the compiler to enforce const-ness of an lvalue (non-reference) but don't know if this is possible in C++. An example:
int foo() { return 5; }
int main() {
// Is there anything I can add to the declaration of foo()
// that would make the following cause a compile-error?
int a = foo();
// Whereas this compiles fine.
const int a = foo();
}
This is not really possible with something like an int because you need to give access to read the int and if they can read the int then they can copy it into a non-const int.
But from your comments it sounds like what you have in reality is not an int but a more complex user defined type, some sort of container perhaps. You can easily create an immutable container. This container could be a wrapper, or alternative implementation of your existing container. It then doesn't matter if the caller uses a const or non-const variable it is still immutable.
class MyClass {
std::vector<int> data;
public:
MyClass(size_t size) : data(size) {}
int& operator[](size_t index) { return data[index]; }
int operator[](size_t index) const { return data[index]; }
size_t size() const { return data.size(); }
};
class MyClassImmutable {
MyClass mc;
public:
MyClassImmutable(MyClass&& mc) : mc(std::move(mc)){}
int operator[](size_t index) const { return mc[index]; }
size_t size() const { return mc.size(); }
const MyClass& get() const { return mc; }
};
MyClassImmutable foo() {
MyClass mc(100);
mc[10] = 3;
return mc;
}
void func(const MyClass& mc);
int main() {
MyClassImmutable mci = foo();
std::cout << mci[10] << "\n"; // Can read individual values
//mci[10] = 4; // Error immutable
func(mc.get()); // call function taking a const MyClass&
}
Live demo.
Of course there is nothing to stop the caller from copying each and every value from your immutable container and inserting them into a mutable container.
Edit: An alternative approach might be to return a smart pointer-to-const. The only downside is you have to pay for a dynamic memory allocation:
std::unique_ptr<const MyClass> foo() {
auto mc = std::make_unique<MyClass>(100);
(*mc)[10] = 3;
return mc;
}
void func(const MyClass& mc);
int main() {
auto mc = foo();
std::cout << (*mc)[10] << "\n"; // Can read individual values
//(*mc)[10] = 4; // Error const
func(*mc); // can pass to a function taking a const MyClass&
}
It's not possible. foo() has no way of knowing about the type of the left hand side of the assignment, because when the assignment itself happens, foo() is already evaluated. The best you could hope for is to change the return value, to try and cause a type-based error on the initialization:
#include <type_traits>
struct my_int {
const int m;
template<typename T, typename std::enable_if<std::is_const<T>::value, T>::type* = nullptr>
constexpr operator T() const {return m;}
};
constexpr my_int foo() { return {5};}
int main() {
const int a = foo();
int b = foo();
}
Live example
But this will also not work, because the typename in the template will never be substitued by a const-qualified type (in this specific case, it will be int for both lines in main()).
As the following is possible
const int x = 4;
int y = x;
the C++ language will not provide such a mechanism.
Remains making a int const by a macro mechanism.
#define int_const_foo(var) const int var = ___foo()
int_const_foo(a);
Drawback: foo cannot be hidden, and the syntax is no longer C style.
#include <iostream>
void doSomething (int x) {std::cout << "Do something with " << x << std::endl;}
struct Base {
virtual int foo() const {return 5;}
virtual int goo() const {return 6;}
virtual int hoo() const {return 7;}
void noTemplatePattern() const {
// Code A
if (Base::foo() < 6) {
// Code B
}
doSomething (Base::goo());
// Code C
if (Base::hoo() > 10) {
// Code D
}
}
void templatePattern() const {
// Code A
if (foo() < 6) {
// Code B
}
doSomething (goo());
// Code C
if (hoo() > 10) {
// Code D
}
}
};
struct Derived : Base {
virtual int foo() const override {return 12;}
virtual int goo() const override {return 13;}
virtual int hoo() const override {return 14;}
};
int main() {
Derived d;
d.noTemplatePattern();
d.templatePattern();
}
How best to avoid repeating the codes contained in Code A, Code B, Code C, Code D, etc... other than creating helper functions for each? Is there a more generic way? I have functions that are identical except one uses the Template Pattern, and the other doesn't. The body of code between the virtual functions are identical. If I define a helper function for each identical part, it gets really messy, and there will be too many of them too.
In case you want more clarification, here is a snippet of my production code illustrating this. SpellCaster is derived from LivingBeing, and LivingBeing::cannotAttackLongRange(int) is overridden by SpellCaster::cannotAttackLongRange(int).
inline std::set<LivingBeingProxy*> LivingBeing::unattackableTargets() const {
std::set<LivingBeingProxy*> nonTargets;
if (isCharmed()) {
for (auto it = std::next(getStatesList(CHARM_SPELL).begin(), 1); it != getStatesList(CHARM_SPELL).end(); ++it)
nonTargets.emplace (std::dynamic_pointer_cast<CharmedStateBase>(*it)->getCharmer());
}
for (LivingBeingProxy* x : getLocation()->allBeingsAlive()) {
if ( (x->heightAboveGround() > damageInflictor(0)->getReach()) && !canFly()
&& LivingBeing::cannotAttackLongRange(distanceBetween(this, x->getActual()))) //*** virtual method here!
{nonTargets.emplace(x); continue;}
if ( (x->heightAboveGround()) < 0 && (x->getTerrain() == InWater) && !canSwim() )
{nonTargets.emplace(x); continue;}
}
// ...
return nonTargets;
}
inline std::set<LivingBeingProxy*> LivingBeing::unattackableTargetsIncludingBySpells() const {
std::set<LivingBeingProxy*> nonTargets;
if (isCharmed()) {
for (auto it = std::next(getStatesList(CHARM_SPELL).begin(), 1); it != getStatesList(CHARM_SPELL).end(); ++it)
nonTargets.emplace (std::dynamic_pointer_cast<CharmedStateBase>(*it)->getCharmer());
}
for (LivingBeingProxy* x : getLocation()->allBeingsAlive()) {
if ( (x->heightAboveGround() > damageInflictor(0)->getReach()) && !canFly()
&& cannotAttackLongRange (distanceBetween(this, x->getActual()))) //*** virtual method here!
{nonTargets.emplace(x); continue;}
if ( (x->heightAboveGround()) < 0 && (x->getTerrain() == InWater) && !canSwim() )
{nonTargets.emplace(x); continue;}
}
// ...
return nonTargets;
}
LivingBeing::unattackableTargets() computes all enemies that are not attackable by ordinary weapons, while LivingBeing::unattackableTargetsIncludingBySpells() computes all enemies that are not attackable by ordinary weapons and spells. A SpellCaster will want to call the first when attacking with an ordinary weapon, and will want to call the second when attacking with a spell.
With template and CRTP, if appropriate, you may do something like:
template <typename T, typename D>
void helper(const D& base)
{
// Code A
if (base.T::foo() < 6) {
// Code B
}
doSomething (base.T::goo());
// Code C
if (base.T::hoo() > 10) {
// Code D
}
}
struct Base {
virtual ~Base() = default;
virtual int foo() const {return 5;}
virtual int goo() const {return 6;}
virtual int hoo() const {return 7;}
void noTemplatePattern() const
{
// use Base::foo, Base::goo and Base::hoo
helper<Base>(*this);
}
#if 0
virtual void templatePattern() const = 0;
#endif
};
template <typename Derived>
struct BaseImpl : Base {
template <typename Derived>
void BaseImpl<Derived>::templatePattern() const {
// use Derived::foo, Derived::goo and Derived::hoo
helper<Derived>(static_cast<const Derived&>(*this));
}
};
Live example
If templatePattern / noTemplatePattern are long and complicated and boo, goo and hoo are simple, you could do the following:
struct Base {
virtual int foo(bool = false) const {return 5;}
virtual int goo(bool = false) const {return 6;}
virtual int hoo(bool = false) const {return 7;}
void Pattern(bool base) const {
// Code A
if (foo(base) < 6) {
// Code B
}
doSomething (goo(base));
// Code C
if (hoo(base) > 10) {
// Code D
}
}
};
struct Derived : Base {
int foo(bool base = false) const override {return base ? Base::foo() : 12;}
int goo(bool base = false) const override {return base ? Base::goo() : 13;}
int hoo(bool base = false) const override {return base ? Base::hoo() : 14;}
};
int main() {
Derived d;
d.Pattern(true); // d.noTemplatePattern();
d.Pattern(false); // d.templatePattern();
}
Not exactly elegant, but might work in a particular situation.
NB: If you use override keyword, you don't need to repeat virtual keyword.
One solution with Tag dispatching (but require more code for foo, goo, hoo)
struct Base {
virtual int foo() const {return foo(std::false_type());}
virtual int goo() const {return goo(std::false_type());}
virtual int hoo() const {return hoo(std::false_type());}
void noTemplatePattern() const { doIt (std::false_type()); }
void templatePattern() const { doIt (std::true_type()); }
private:
template <typename T>
void doIt (T t) const {
// Code A
if (foo(t) < 6) {
// Code B
}
doSomething (goo(t));
// Code C
if (hoo(t) > 10) {
// Code D
}
}
// tag dispatching between virtual call and Base::call
int foo(std::false_type) const {return 5;}
int goo(std::false_type) const {return 6;}
int hoo(std::false_type) const {return 7;}
int foo(std::true_type) const {return foo();}
int goo(std::true_type) const {return goo();}
int hoo(std::true_type) const {return hoo();}
};
Live example
Ok, this is one solution I thought of, but though it works I don't know if it is considered any good (need some opinions). But at least all repeated code is avoided, and thus any changes to those parts needs only be made once:
#include <iostream>
void doSomething (int x) {std::cout << "Do something with " << x << std::endl;}
struct Base {
virtual int foo() const {return fooBase();}
virtual int goo() const {return gooBase();}
virtual int hoo() const {return hooBase();}
virtual void voidFunction() const {voidFunctionBase();}
void noTemplatePattern() const {
doIt (&Base::fooBase, &Base::gooBase, &Base::hooBase, &Base::voidFunctionBase);
}
void templatePattern() const {
doIt (&Base::foo, &Base::goo, &Base::hoo, &Base::voidFunction);
}
private:
void doIt (int(Base::*a)()const, int(Base::*b)()const, int(Base::*c)()const,
void(Base::*d)()const) const {
// Code A
if ((this->*a)() < 6) {
// Code B
}
doSomething((this->*b)());
// Code C
if ((this->*c)() > 10) {
// Code D
}
(this->*d)();
// Code E
}
int fooBase() const {return 5;}
int gooBase() const {return 6;}
int hooBase() const {return 7;}
void voidFunctionBase() const {std::cout << "Base::voidFunction() called.\n";}
};
struct Derived : Base {
virtual int foo() const override {return 12;}
virtual int goo() const override {return 13;}
virtual int hoo() const override {return 14;}
virtual void voidFunction() const override {std::cout << "Derived::voidFunction() called.\n";}
};
int main() {
Derived d;
d.noTemplatePattern();
d.templatePattern();
}
Output:
Do something with 6
Base::voidFunction() called.
Do something with 13
Derived::voidFunction() called.
Opinions? A better solution?
A possibility, if applicable, is to slice your object:
void noTemplatePattern() const {
// copy only Base part (slicing). Require that Base is constructible
Base(*this).templatePattern();
}
Live example
There is a pretty easy, no-nonsense solution for this: Just replace the two functions by one which takes a parameter bool includeSpells. Then you can just check for this parameter in the function and execute the appropriate function call. The rest of the function remains unchanged.
I have the following code:
class STFDataPoint {
public:
virtual ImagePoint get_patch_top_left() const = 0;
virtual ImagePoint get_patch_bottom_right() const = 0;
virtual std::string get_image_filename() const = 0;
virtual ~STFDataPoint() = 0;
};
inline STFDataPoint::~STFDataPoint() {}
class TrainingDataPoint : public STFDataPoint{
private:
int row;
int col;
std::string class_label;
ImagePoint patch_top_left;
ImagePoint patch_bottom_right;
std::string image_filename;
public:
TrainingDataPoint(int row, int col, std::string class_label,
const ImagePoint & top_left,
const ImagePoint & bottom_right,
std::string image_filename);
std::string get_class_label() const;
inline bool operator==(const TrainingDataPoint& other) const{
return other.class_label == this->class_label;
}
inline bool operator!=(const TrainingDataPoint& other) const{
return !(*this == other);
}
virtual ImagePoint get_patch_top_left() const;
virtual ImagePoint get_patch_bottom_right() const;
virtual std::string get_image_filename() const;
};
And I am trying to run the following:
bool do_something(vector<STFDataPoint>& data_point){
return true;
}
int main(int argc, char* argv[]) {
ImagePoint left = ImagePoint(2,3);
ImagePoint right = ImagePoint(2,3);
TrainingDataPoint a = TrainingDataPoint(1,2,"",left, right, "");
vector<TrainingDataPoint> b;
b.push_back(a);
do_something(b);
}
But get the following error:
invalid initialization of reference of type ‘std::vector<STFDataPoint>&’ from expression of type `std::vector<TrainingDataPoint>`
however if I change the signature of do_something() to take in a STFDataPoint (not a vector of them) it runs fine. Can some one please explain why this is and also if there is a work around?
Thanks
Since vector<TrainingDataPoint> is not a subtype of vector<STFDataPoint> you cannot do this. Vectors are not covariant in parameter type.
However you can template do_something to make it work:
template <typename T>
bool do_something(vector<T>& data_point){
//common actions like
ImagePoint leftPatch = data_point[0].get_patch_top_left();
return true;
}
The type vector<TrainingDataPoint> is not the same as vector<STFDataPoint> and there is no conversion between the two. vector<A> is not a base type of vector<B>, even if A is a base of B.
What could work is to have a container of pointers or smart pointers to the base type, and change the function to use that:
bool do_something(vector<std::unique_ptr<STFDataPoint>>& data_point){
return true;
}
std::vector<std::unique_ptr<STFDataPoint>> b;
b.push_back( std::unique_ptr<STFDataPoint>(new TrainingDataPoint(1,2,"",left, right, "") ); // fill with any derived types of STFDataPoint
do_something(b);
Why can't I use the function ColPeekHeight() as an l-value?
class View
{
public:
int ColPeekHeight(){ return _colPeekFaceUpHeight; }
void ColPeekHeight( int i ) { _colPeekFaceUpHeight = i; }
private:
int _colPeekFaceUpHeight;
};
...
{
if( v.ColPeekHeight() > 0.04*_heightTable )
v.ColPeekHeight()-=peek;
}
The compiler complains at v.ColPeekHeight()-=peek. How can I make ColPeekHeight() an l-value?
Return the member variable by reference:
int& ColPeekHeight(){ return _colPeekFaceUpHeight; }
To make your class a good one, define a const version of the function:
const int& ColPeekHeight() const { return _colPeekFaceUpHeight; }
when I declare the function with the
two consts
When you want to pass an object into a function that you don't expect it to modify your object. Take this example:
struct myclass
{
int x;
int& return_x() { return x; }
const int& return_x() const { return x; }
};
void fun(const myclass& obj);
int main()
{
myclass o;
o.return_x() = 5;
fun(o);
}
void fun(const myclass& obj)
{
obj.return_x() = 5; // compile-error, a const object can't be modified
std::cout << obj.return_x(); // OK, No one is trying to modify obj
}
If you pass your objects to functions, then you might not want to change them actually all the time. So, to guard your self against this kind of change, you declare const version of your member functions. It doesn't have to be that every member function has two versions! It depends on the function it self, is it modifying function by nature :)
The first const says that the returned value is constant. The second const says that the member function return_x doesn't change the object(read only).
It can be rewritten like:
class View
{
public:
int GetColPeekHeight() const { return _colPeekFaceUpHeight; }
void SetColPeekHeight( int i ) { _colPeekFaceUpHeight = i; }
private:
int _colPeekFaceUpHeight;
};
...
{
cph = v.GetColPeekHeight();
if ( cph > 0.04 * _heightTable )
v.SetColPeekHeight( cph - peek );
}