Let:
class CLASS{
void foo() {};
static void staticFoo() { foo(); }
};
Why would calling a nonstatic method from a static one be a problem? How do I go around this?
Judging by your question, it appears that you are not very familiar with object oriented programming. Writing C++ classes and not knowing object oriented programming is not the best idea. It's also not something we can sum up in a StackOverflow answer. It's best if you search for this topic and learn at least the basics before continuing. It actually would take less time that you'd imagine to get familiar with the basics.
This MIT class's presentation on object oriented programming is decent. Object oriented programming in C++
But to answer your question: why can't we call up a non-static method from a static method. Well when you define a C++ class, you're describing the model, or blueprint for making instances of something. For example, you could define a class Animal like this:
class Animal {
public:
void set_name(std::string name) { this->name_ = name; }
const std::string& get_name() const { return this->name_; }
private:
std::string name_;
};
We obviously have methods to set and get the name of this Animal class. Note that much like in the real world, we don't just name the abstract idea of animals, we'd name our own pet or some known specific animal, that happens to be one instance of an animal. This might receive criticism but you can kinda think of it as the difference between dog and the dog. The latter is a specific dog that all involved parties are aware of. That's why methods set_name and get_name need to know which animal you're talking about.
Consider this:
Animal my_dog;
my_dog.set_name("stripes");
Animal my_cat;
my_cat.set_name("katz");
The method set_name updates the name of my_dog and my_cat. We had to tell the set_name which instance we're talking about. Methods like these are instance methods, you can have a pointer to yourself which in C++ is designated by this. That's how you can update attributes about different instances. A static method doesn't receive this context and therefor won't be able to call instance methods unless of course it has access to one of these instances. For example:
static void print_animal(const Animal& animal) {
std::cout << animal.get_name() << std::endl;
}
After all of this, hopefully it makes sense why we can't just call Animal::set_name.
Why can't a nonstatic method be called from a static one?
A non-static member function can be called from a static member function.
Why would calling a nonstatic method from a static one be a problem?
It's not a problem. The problem is that you've not invoked the non-static member function on an object. Non-static member functions cannot be invoked without an object argument.
The syntaxes to invoke a non-static member function are following:
instance.mem_fun(arguments);
pointer->mem_fun(arguments);
Non-static member functions are special in that they can invoke other non-static member functions without explicit instance argument. The argument is implicitly this. Static member functions don't have this, and the exception doesn't apply to them.
How do I go around this?
Use one of the syntaxes shown above. You need to consider what instance you intend to use as the object argument of the non-static member function.
but why couldn't foo be called statically ...
Because foo is a non-static member function. Non-static member functions cannot be called statically.
... if the call is made from a static function?
Where the function is called from has no effect on whether it can be called statically.
Related
Consider the following:
class RecordCommon {
public:
virtual const char* GetShortName(void) const = 0;
...
virtual void DoSomeWork(void);
};
class RecordCLDT : public RecordCommon {
virtual const char* GetShortName(void) const { return "CLDT"; }
};
void RecordCommon::DoSomeWork(void) {
...
log(GetShortName());
...
}
What I want to have is static method like RecordCLDT::GetShortName(void) that would return"CLDT" without doing major refactoring of the project. Maybe this could be done by some macro or smart template technique?
I need to have RecordCommon::DoSomeWork(void) calling the correct GetShortName() function which it wouldn't if I just replace virtual GetShortName() with static one.
Re-writing every single child class of RecordCommon would be very time-consuming especially since virtual GetShortName() is used in the code.
No, and you shouldn't want to. Anything you would do yourself would end up behaving like virtual anyway.
Just because you aren't accessing any of the data members of RecordCLDT, it doesn't mean you can make it static, you still need it to be an override of the base class member to call the right thing.
virtual functions work because there is information hidden in the object that tells the system what object the pointer/reference really points to. This is what allows the correct function to be called for a given object.
If you want to remove virtual functions, you must replace this functionality. That is, instead of having hidden data in the object that says which kind of object it is, you must have explicit data in the object, which different functions will look at to tell which type it really is and therefore how to behave.
This is not a trivial thing to do, and how best to do it depends on a variety of factors. You can't just make a static member, rip out some virtuals, and expect everything to still work. The data that says what type the object is still has to be there and must be accessible from the base class. If you remove the implicit data, you must add explicit data.
effective c++ item 9
Can function createLogString be virtual?
class BuyTransaction: public Transaction {
public:
BuyTransaction( parameters ):Transaction(createLogString(parameters)) { ... }
...
private:
static std::string createLogString( parameters );
};
Yes, it can be virtual (instead of static). It will still be statically bound during construction however, and not dispatched dynamically.
The only point to making it virtual is if it is also used in some other member of the class (that is not a constructor/destructor) and a deriving class can possibly override it to do something useful for those members. However, that starts having the faint traces of a design smell.
Scott's advice of "Never call virtual functions during construction or destruction" stems from the fact that it rarely if ever accomplishes anything useful.
Suppose we have a class, "Animal", and subclasses, "Cat" and "Dog".
Let's say we want to allow both "Cat" and "Dog" to make a noise (cat: "meow" - dog: "woof") when we pass their objects into an intermediate function for any "Animal".
Why must we use a virtual method to do this? Couldn't we just do Animal->makeNoise() without defining a virtual method in "Animal"? As "Cat" and "Dog" are both animals, wouldn't it be clear that "makeNoise()" is referring to the Animal which has been passed to the function?
Is this just a matter of syntax or something more? I'm pretty sure in Java we don't have to do this.
In Java, all member functions are virtual by default (except static, private, and final ones).
In C++, all member functions are non-virtual by default. Making functions virtual adds overhead - both runtime and to object size - and the C++ philosophy is don't pay for what you don't use. Most of my objects are not polymorphic, so I shouldn't have to pay for polymorphism unless I need it. Since you need Animal::makeNoise() to be virtual, you must explicitly specify it as such.
C++ is designed to run with as little overhead as possible, trusting the programmer to make the correct call. Essentially, it 'gives you the gun and the option to shoot yourself in the foot', as one of my friends likes to say often. Speed and flexibility are paramount.
To correctly cause true polymorphic behavior, C++ requires it be specified. However! It is only required to be specified in the base class, as all derived class will inherit the virtual member functions. If a member inherits a virtual member function, it is good practice to place 'virtual' in the declaration, but not required.
ADTs usually implement pure virtual functions to indicate that the derived classes MUST implement the function. Such as:
animal makeNoise() = 0; /*Indicates this function contains no implementation.
and must be implemented by derived classes in order to function.*/
Again, it is not required the derived classes include 'virtual' in their inherited members so long as the base class includes this.
If you want to deduce the type of the Animal and then call make_sound(), then you would have to do a dynamic_cast on the animal object for each and every child of animal. This would include any class that is directly or indirectly a child of the Animal class.
This is both difficult to maintain and very painful to any change eg. Adding new class as a child to the Animal class.
Since c++ philosophy is efficiency, you will have to ask the compiler to provide you with run-time polymorphism as it is costly. How would you do that? By stating the make_sound() function as virtual. This creates a vtable ( a table of functions pointers ) which refers to an address of make_sound() which differs to based on the type of the object.
No need to downcast as indirection handles everything for you. What could be hundreds of lines of code is just a single line of code. That is the power of indirection!!
You could say that you have to do it because that's one of the rules of the language.
There's a reason its helpful though.
When trying to validate the code that uses an Animal, the complier knows what functions exist on an Animal. Its possible to tell whether the code is correct without checking all classes that derive from animal. So that code doesn't need to depend on all those derived classes. If you derive a new class from Animal but forget to implement the makeNoise function that's an error in the new class not the code that uses the Animal base class and the complier can point you towards that error. Without the virtual function declared in Animal there would no way to tell if its the calling code or the new class that is in error.
A key point here is that these errors would be caught at compile-time for C++ because of its static typing. Other languages can allow dynamic typing, which can make some things easier but, the errors would only be spotted at runtime.
In Java, all functions are virtual by default. In C++ they are not, so when you call a non-virtual function on a pointer of a given type, that type's implementation of that function is invoked with the object's address as this.
class Animal {
public:
void sound() { std::cout << "splat\n"; }
virtual void appearance() { std::cout << "animaly\n"; }
};
class Cat {
public:
void sound() { std::cout << "meow\n"; }
virtual void appearance() { std::cout << "furry\n"; }
};
int main() {
Animal a;
Cat c;
Animal* ac = new Cat;
a.sound(); // splat
a.appearance(); // animaly
c.sound(); // meow
c.appearance(); // furry
ac->sound(); // splat
ac->appearance(); // furry
}
This would occur when you wanted to write a function that generalized on "Animal" rather than requiring a specific derived class pointer.
In java you use virtual methods too.
It improves the loosely coupling of your software.
For example, you can use a library and don't know which animal they use internally. There is a animal implementation you don't know and you can use it because it's an animal. You get the animal with a library.getAnimal method. Now you can use their animal without to know which noise it makes, because they have to implement the method makeNoise.
Edit: So to answer your question, c++ wants a explicit declaration and in java it is implicit. so yes it is a kind of language specific idiosyncracy.
Is there a way to call a non static class member method from another method that is contained within the main class in c++? If so, what would the code look like?
Problem is, I can't declare this specfic method as static, because it uses other methods within the same class that then don't work if I make the one static.
I'm trying to use:
MyClass::myClassMethod();
from a method within the main class, but it gives me the error: a non static member reference must be relative to a specific object.
To clarify, myClassMethod() uses other methods within MyClass like:
void myClassMethod() {
...
anotherClassMethod();
}
so if I were to make myClassMethod static it would interfere with calling anotherClassMethod().
What is the deal with calling non-static member function from a static member function?
Every non static member function is passed an this pointer implicitly in addition to the parameters you pass, the pointer passed is then dereferenced to refer class object members However static functions are not passed with the implicit thispointer and hence one cannot call any non static member function inside a static member function because there is no this to do so.
What is the solution, If you want to do it anyways?
You will need some mechanism to get the pointer to the object inside the static method and then you can call the member function using that pointer.
How to do that?
You will have to store the pointer to class object globally, or pass it as an instance in one of the function arguments to the static method.
However, both of above are workarounds, the important thing to note here is If you feel the need of calling a non static member function through a static member function then there is something wrong in your design.
On Second thoughts maybe I mis-read your Question before, Probably, Your question is:
How to call a non-static member function of a class from main?
You need a instance of the class to call non-static member functions.
So simply,
MyClass obj;
obj.myClassMethod();
And calling any other member function from within myClassMethod() would simply be:
void myClassMethod()
{
//...
anyOtherMyClassNonStaticMemberFunction();
//...
}
A static method is one that doesn't run on any particular object. It's a lot like a standalone function outside of a class, except that it's allowed to access private members in its class.
If you anotherClassMethod() is non-static, that means it has to be called on a specific object, an instance of the class. Because it's called on an object, it can access data stored in that object (non-static member variables). If myClassMethod() is static and you implement it as
void MyClass::myClassMethod() {
anotherClassMethod();
}
That won't work because anotherClassMethod() expects to be called on a specific object, but myClassMethod() doesn't have one. But if you know what object you want to call it on, you can do it as an ordinary method call on an object:
void MyClass::myClassMethod(MyClass &object) {
object.anotherClassMethod();
}
The object doesn't have to be passed in as an argument; it could be a static member variable in the class, for example:
class MyClass {
private:
static MyClass theInstance;
// ...
};
void MyClass::myClassMethod() {
theInstance.anotherClassMethod();
}
Ultimately, the question you need to ask yourself is: why is myClassMethod() static, and why is anotherClassMethod() non-static? Take a step back, think about what myClassMethod() is supposed to do. Does it make sense to call it when you don't have an instance to work with? If so, why does it need to call a method that expects to work with an instance?
The only way to call a non static method of a class is through an instance of that class. So you would need something like this...
MyClass myClass;
myClass.myClassMethod();
I think that maybe you could use the singleton pattern, keep a instance of the class in global. like a utility class.
I know this question has a similar title to this: C++: calling member functions within constructor? but I am asking a more general question.
Is it good practice to call member functions from within a constructor? It makes reading the code easier and I prefer the encapsulation type way of doing it (ie. each block of code has a single objective).
An illustrative example, in python:
class TestClass:
def __init__(self):
self.validate()
def validate(self):
# this validates some data stored in the class
Is this a better way of doing it than writing the validate code inside the constructor? Are there drawbacks to this method? For example is it more costly with the function overhead?
I personally prefer it for readability but that's just my preference.
Cheers
I don't think there is anything inherently wrong in calling member functions from a constructor provided that they are not virtual functions.
The problem with calling virtual member functions from a constructor is that a subclass can override the function. This will cause the constructor to call the overridden implementation in the subclass, before the constructor for the subclass part of the object has been called.
In Java, any one of the private, static or final access modifiers will make the method safe to call from a constructor by preventing a virtual call to the superclass method. I don't think these techniques are available in Python.
There is at least one associated "gotcha" you should be aware of:
N3797 12.6.2/14
Member functions (including virtual member functions, 10.3) can be called for an object under construction. Similarly, an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_cast (5.2.7). However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result
of the operation is undefined. [Example:
class A {
public:
A(int);
};
class B : public A {
int j;
public:
int f();
B() : A(f()), // undefined: calls member function
// but base A not yet initialized
j(f()) { } // well-defined: bases are all initialized
};
class C {
public:
C(int);
};
class D : public B, C {
int i;
public:
D() : C(f()), // undefined: calls member function
// but base C not yet initialized
i(f()) { } // well-defined: bases are all initialized
};
— end example]
The main problem with this is that the member function has to work with an object that may be only partially initialized. And if it (even accidentally) passes a reference to the object somewhere else, other code has to od the same. This can get pretty confusing and error-prone, especially once you start overriding such a function in a subclass.
So in general, this practice should be avoided or at least confined to functions that can't be overriden, and they should never pass a reference to the object being constructed to any other code.
I'm more familiar with C++ than Python, but I see no problem with calling member functions from constructors, especially when this practice is able to factor out similar code from multiple constructors. Anything that reduces redundancy is good in my books.
From a readability point of view it is definitely better. One thing you might have to ask yourself here though is whether the validate method is allowed to run after the object is initialized. If that is not the case, you can a) use some kind of private initialized variable or b) use the Builder pattern to get your objects into a valid state before using them.
Make sure the function is private. You do not want to mess with subclasses overriding it (Unless this is desired by design, in which case make it abstract/virtual).
first, this member function cannnot be virtural function,
second, this member function must be implemented in the same file, if you declare it in *.h, then implement it in *.cpp, gcc/clang will report this error undefined reference to