I can't see what's wrong with my code. I have a an std::vector which is a private member of my class Foo. It is not declared as const, even when the error the compiler gives suggests so.
(At Foo.h)
private:
std::vector<std::string> tableBackup;
I'm calling a function (from Foo.cpp):
BackupTable(this->tableBackup);
This method is into DatabaseLoad.cpp and .h:
public:
void BackupTable(std::vector<std::string> &tableBackup);
Defined as:
void DatabaseLoad::BackupTable(std::vector<std::string> &tableBackup){
//whatever...
}
I'm getting the following error when I call the method from Foo.cpp:
No matching function for call to 'DatabaseLoad::BackupTable(const std::vector<std::basic_string<char> > &)'
What's the problem? Currently using C++11, but I guess this has nothing to do with that.
You are calling the BackupTable function in a context where the DatabaseLoad object is const-qualified, therefore the compiler is expecting a call to a const-reference.
If you are not planning on modifying the vector, you should declare the function as:
void BackupTable(const std::vector<std::string>& tableBackup);
I can guess that you are calling BackupTable from const method of Foo class
You seem to be calling BackupTable(this->tableBackup); inside a member function which is qualified as const. This means that this is of type const Whatever*, and thus all data members are implicitly const-qualified inside this member function as well. So they cannot be bound to a non-const reference.
You have two sane options:
If BackupTable does not modify its argument, it should accept it as const & instead of just &.
If it does modify its argument, it means the calling function modifies its this object, so it should not be marked as const.
A third (far less likely) option is that tableBackup is actually an implementation details of your class and the fact that it changes does not affect the "logical constness" of the class. If that is so, you can mark it as mutable (that way, even const functions will be able to modify it). At the same time, you must introduce some form of synchronisation mechanism (e.g. a mutex) whenever you access the mutable tableBackup (or any mutable member). The reason is that all of the standard library expects const operations to be thread-safe. An emerging idiom for this is adding a private member like this:
mutable std::mutex mutables;
And locking mutables whenever you access (even just for reading!) a mutable member.
I think that 'this' is const in ' BackupTable(this->tableBackup);'. You call the ' BackupTable' in a 'Foo() const' function.
Related
I need to establish a hash table using a hasher different from the default one, so I write something like:
class foo {
public:
...
private:
struct myhasher {
size_t operator() (myclass bar) { return hash_calculation bar; }
}
static size_t hash_calculation (myclass bar) {
// do some calculation
}
hash_map<myclass, myhasher> myhashmap;
}
It works. Now for some reason I have to write a non-static member function to replace hash_calculation, say, it needs a non-static member of the class as an argument. Then the whole thing failed because I cannot use a non-static method in a nested struct.
This is somehow similar to another widely discussed problem: how to use a non-static function to do comparison or sorting. See for example:
Using a non-static class member inside a comparison function
and
C++ std list sort with custom comparator that depends on an member variable for the object instance . They both established a functor instead of a function as the comparator. However in my case this trick does not work because I need a class name inside the hash_map definition, not a specific struct object. What should I do? Thanks in advance for your help!
You can't. How is the hash_map supposed to know which instance of myhasher should be used when calling myhaser::hash_calculation?
hash_map isn't part of the standard C++ library, not even in C++11, so it's a custom class, and you have included no information about how it works. If there is a way for it to take some sort of constructor argument for which myhasher it should use, you're in luck. But it doesn't sound like it.
Also, you're using pass by value when you probably mean to pass in a const reference. Passing by value is likely going to be really slow and inefficient.
The standard "hash-map", i.e., std::unordered_map<K, V, H, E, A> takes a hash object of type H as constructor argument. A copy of this object is used to determine the hash for the object by way of the function call operator. This way can provide some context. Obviously, you were already using a non-static function call operator but you choose to delegate to a static member.
AFAIK, in C++, invoking another member function within a member of function of the same class should not require the "this" prefix as it is implicit. However, in the specific case of using function pointers, the compiler requires it. The following code compiles correctly only if I include the "this" prefix for the call via func pointer -
When function pointers are used can the compiler deduce when it points a member func of the same class?
class FooBar
{
private:
int foo;
public:
FooBar()
{
foo = 100;
}
int GetDiff(int bar)
{
return abs(foo - bar);
}
typedef int(FooBar::*MyFuncPtr)(int);
void FooBar::Bar()
{
MyFuncPtr f = &FooBar::GetDiff;
(this->*f)(10);
GetDiff(10);
}
};
It's required, because member function pointers (which are not the same thing as function pointers) are not bound, and you can use them with different objects.
(this->*f)(10);
(foo.*f)(10);
// etc.
When you invoke an instances member function the this pointer is implicitely put to the function parameters. Thus you need to specify this also when invoking that function via a function pointer.
f isn't a member of the class, but a local variable, you could also specify another instance pointer instead of this, so the compiler can't deduce that. Same for member function pointers as class member variables.
The simple question is that it is a matter of language design and the language was designed this way.
Inside a member function, and to ease the common syntax when the compiler encounters an identifier it performs lookup starting from this class (plus ADL on the arguments), and if the lookup finds an unambiguous non-static member of this type (or of a base type) then the compiler will inject this-> for you (that is, applies operator-> to the this pointer).
In the case of a pointer to member the process is quite different. The pointer (which is not really a pointer, but for the sake of argument) is found by lookup, but it is your responsibility to provide the object on which it will be called and use the appropriate operator (either .* for calling a pointer to member on a reference, or ->* for calling the member on a pointer).
Note that the operators that are called are different, and that the process is different altogether (in one case lookup finds a member, in the other it finds a variable that happens to be pointer-to-member), but the most important part is that calling pointers to members is infrequent enough, and calling them on this is even less frequent that it does not not to warrant an exemption on the syntax for a small use case.
f isn't a member of FooBar. So if you want to call f on an instance of FooBar, you have to tell it which instance.
In your example, f does contain a member of FooBar, but the compiler doesn't know that.
This happens because of the way the C++ runtime handles classes while you are not looking.
Basically it would be inefficient to store the function pointers in the instance, so the compiler builds a class specific table with function pointers that have the same arity as the member functions you defined and that get the this pointer passed at runtime (AFAIK visualc passes the pointer via ecx, I'm not entirely sure what happens on GCC)
So basically when you do
instance->foo(10);
You are telling the runtime to call function foo with the parameter 10 and pass (instance) as the this pointer, wich is why you have to specifically say which object it has to be called on.
Like this,
bool isEmpty() const { return root==NULL; }
This is isEmpty function, test if the BST is empty or not.
It indicates that the function does not modify any of the members of that class.
Usually, the Interface/declaration(through header file) is made available to the users of the class/functions and not the implementation,So the const makes it clear to the user that the function does not modify any members.
Adding the const also makes the user of the function aware that this const member functions should be used when you have an const object.You cannot call normal member function on a const object of that class,it will result in a compiler error.
That is the reason that the function is marked const even if it is empty.It indicates a contract between the function implementer and the user of the function.
When a function is marked as const, the function can be invoked on a const instance of the class. Invoking a non-const function on a const object will lead to a compile-time error.
Basically, you want to mark all functions that don't change the state of your object as const; this way, you can use const as an immutability declaration and the compiler will enforce it for you, by making sure you can only invoke the const functions.
You can invoke const functions on a non-const instance no problem.
It tells the compiler that the function will not modify the state of the class. Also, const functions are the only functions allowed to be called on const objects.
It indicates that the function is logically constant, that is, as far as users of the class are concerned, the value of the class member is not changed by the function. It is legal to call const functions on const references and through const pointers.
I'm wondering if a class's member function should be const if it calls other functions that modify its data members. A good example would be a public member function that uses private member functions to do the brunt of the work.
void Foo::Show() const { // Doesn't directly modify data members in this function
ShowPig(); // One or all of these functions modify data members
ShowCow();
ShowBar();
}
Maybe not the best example, but you get the idea.
Any Good compiler does not allow this. You should get the compiler error.
The compiler should not allow you to do that. Example below.
//MS VC 2008
class Foo
{
int m_iBar;
void ThisIsConstFunc() const
{
m_iBar = 9; //error C2166: l-value specifies const object
ThisIsNonConst(); //error C2662: 'Foo::ThisIsNonConst' : cannot convert 'this' pointer from 'const Foo' to 'Foo &'
}
void ThisIsNonConst()
{
m_iBar = 9;
}
};
If a function calls functions that modify certain data, then it should be said that the function itself modifies data. It just happens to be abstracted.
So no, that function should not be const.
C++ provides the mutable keyword for the rare case that you actually want to allow this. And there are times where it happens, for instance if your function does not change the logical state of the object, but may modify one or more members of the object.
These cases are very rare. In the vast majority of cases you should mark the member function const if neither that function nor any function it calls modifies the state of the object.
Yes, the compiler won't let you, as pointed out. Of course you can do it anyway but if the function needs to be const usually it's a bad idea. If it doesn't need to be const, don't just put it in there for no reason. There's really not much benefit to const and many potential serious problems, you just get forced into it at times.
Given a declaration like this:
class A {
public:
void Foo() const;
};
What does it mean?
Google turns up this:
Member functions should be declared with the const keyword after them if they can operate on a const (this) object. If the function is not declared const, in can not be applied to a const object, and the compiler will give an error message.
But I find that somewhat confusing; can anyone out there put it in better terms?
Thanks.
Consider a variation of your class A.
class A {
public:
void Foo() const;
void Moo();
private:
int m_nState; // Could add mutable keyword if desired
int GetState() const { return m_nState; }
void SetState(int val) { m_nState = val; }
};
const A *A1 = new A();
A *A2 = new A();
A1->Foo(); // OK
A2->Foo(); // OK
A1->Moo(); // Error - Not allowed to call non-const function on const object instance
A2->Moo(); // OK
The const keyword on a function declaration indicates to the compiler that the function is contractually obligated not to modify the state of A. Thus you are unable to call non-const functions within A::Foo nor change the value of member variables.
To illustrate, Foo() may not invoke A::SetState as it is declared non-const, A::GetState however is ok because it is explicitly declared const. The member m_nState may not be changed either unless declared with the keyword mutable.
One example of this usage of const is for 'getter' functions to obtain the value of member variables.
#1800 Information: I forgot about mutable!
The mutable keyword instructs the compiler to accept modifications to the member variable which would otherwise cause a compiler error. It is used when the function needs to modify state but the object is considered logically consistent (constant) regardless of the modification.
This is not an answer, just a side comment. It is highly recommended to declare variables and constants const as much as possible.
This communicates your intent to users of your class (even/especially yourself).
The compiler will keep you honest to those intentions. -- i.e., it's like compiler checked documentation.
By definition, this prevents state changes you weren't expecting and can, possibly, allow you to make reasonable assumptions while in your methods.
const has a funny way of propagating through your code. Thus, it's a really good idea to start using const as early and as often as possible. Deciding to start const-ifying your code late in the game can be painful (easy, but annoying).
If you're using a language with static, compile time checks it's a great idea to make as much use of them as possible... it's just another kind of testing really.
Functions with const qualifier are not allowed to modify any member variables. For example:
class A
{
int x;
mutable int y;
void f() const
{
x = 1; // error
y = 1; // ok because y is mutable
}
};
C++ objects can be declared to be const:
const A obj = new A();
When an object is const, the only member functions that can be called on that object are functions declared to be const. Making an object const can be interpreted as making the object readonly. A const object cannot be changed, i.e. no data members of the object can be changed. Declaring a member function const means that the function is not allowed to make any changes to the data members of the object.
Two suggested best practices from experience:
(1) Declare const functions whenever possible. At first, I found this to be just extra work, but then I started passing my objects to functions with signatures like f(const Object& o), and suddenly the compiler barfed on a line in f such as o.GetAValue(), because I hadn't marked GetAValue as a const function. This can surprise you especially when you subclass something and don't mark your version of the virtual methods as const - in that case the compile could fail on some function you've never heard of before that was written for the base class.
(2) Avoid mutable variables when it's practical. A tempting trap can be to allow read operations to alter state, such as if you're building a "smart" object that does lazy or asynchronous i/o operations. If you can manage this with only one small mutable variable (like a bool), then, in my experience, this makes sense. However, if you find yourself marking every member variable as mutable in order to keep some operations const, you're defeating the purpose of the const keyword. What can go wrong is that a function which thinks it's not altering your class (since it only calls const methods) my invoke a bug in your code, and it could take a lot of effort to even realize this bug is in your class, since the other coder (rightly) assumes your data is const because he or she is only calling const methods.
const has a funny way of propagating through your code. Thus, it's a really good idea to start using const as early and as often as possible. Deciding to start const-ifying your code late in the game can be painful (easy, but annoying).
Additionally, you will easily run into problems if methods that should be const aren't! This will creep through the code as well, and make it worse and worse.
that will cause the method to not be able to alter any member variables of the object