If I have two classes called A and B,
Note: The following doesn't compile.
class A
{
public:
static void funcA() {}
void call_funcB() { B::funcB(); } // call class B's function
};
class B
{
public:
static void funcB() {}
void call_funcA() { A::funcA(); } // call class A's function
};
Errors:
error C2653: 'B' : is not a class or namespace name
error C3861: 'funcB': identifier not found
Can you call the static functions of each class?
You have to do this:
class A
{
public:
static void funcA() {}
void call_funcB() ;
};
class B
{
public:
static void funcB() {}
void call_funcA() { A::funcA(); } // call class A's function
};
void A::call_funcB() { B::funcB(); } // call class B's function
This allows A::call_funcB() to see the B declaration.
You need to give the compiler a tip that the other class with be defined because it's a circular dependency.
class B;
class A { ... };
class A; // assuming separate file
class B { ... };
You could make funcA and funcB Friend methods.
Related
I have a class C that inherits both from Ai and B. A and B are unrelated. This is all best explained with the code below. In main(), I have a variable a defined as std::unique_ptr<A>, but initialized with C. I cannot change this definition.
My question is, given a defined like this, how can I call functions defined in B or C or Ai correctly?
#include <memory>
class A
{
public:
void fun_a() {}
};
class B
{
public:
void fun_b() {}
};
class Ai : public A
{
public:
void fun_ai() {}
};
class C: public Ai, public B
{
public:
void fun_c() {}
};
int main()
{
// I cannot change the following definition:
std::unique_ptr<A> a = std::make_unique<C>();
a->fun_a();
//a->fun_b(); // How ?
//a->fun_c(); // How ?
//a->fun_ai(); // How ?
return 0;
}
You can static_cast to C*:
static_cast<C*>(a.get())->fun_b();
static_cast<C*>(a.get())->fun_c();
static_cast<C*>(a.get())->fun_ai();
or you could make it polymorphic:
class A {
public:
virtual ~A() = default;
void fun_a() { std::cout << "fun_a\n"; }
};
and then dynamic_cast:
dynamic_cast<B*>(a.get())->fun_b();
dynamic_cast<C*>(a.get())->fun_c();
dynamic_cast<Ai*>(a.get())->fun_ai();
Note: dynamic_casts to pointer types may fail and return nullptr so, if there's any doubt, check the return value.
Demo
Assuming I have these classes (question marks mark the question what I need to pass here):
class A
{
...
public:
void pass()
{
B ins;
ins.doSth(?????);
}
};
class B
{
...
public:
void doSth(const A &sth)
{
...
}
}
int main()
{
A te;
te.pass();
}
Can you pass an instance of your own class or is this just an example of a failed class structure on my side?
The current object in a member function is *this. You can pass that to another function.
You will have to consider how the classes depend on each other, and that one class cannot use the other class until the declaration is complete.
This would work though:
class A
{
//...
public:
void pass();
};
class B
{
//...
public:
void doSth(const A &sth)
{
//...
}
};
// Here both classes are completely declared
void A::pass()
{
B ins;
ins.doSth(*this);
}
int main()
{
A te;
te.pass();
}
Your class "contains" an instance of each other so you'll face an error of undeclared types. To solve this issue you need to use forward declaration.
And you'll face another problem:
If your methods doSth() and pass() are defined inlinlely then you'll face a problem: "using incomplete types". The workaround this is to implement these methods outside the class so that each object has been fully constructed before used.
The program may look like:
class A;
class B;
class A{
public:
void pass();
};
class B{
public:
void doSth(const A &sth){
}
};
void A::pass(){
B ins;
ins.doSth(*this);
}
int main(){
A te;
te.pass();
return 0;
}
How do I call the parent function from a derived class using C++? For example, I have a class called parent, and a class called child which is derived from parent. Within
each class there is a print function. In the definition of the child's print function I would like to make a call to the parents print function. How would I go about doing this?
I'll take the risk of stating the obvious: You call the function, if it's defined in the base class it's automatically available in the derived class (unless it's private).
If there is a function with the same signature in the derived class you can disambiguate it by adding the base class's name followed by two colons base_class::foo(...). You should note that unlike Java and C#, C++ does not have a keyword for "the base class" (super or base) since C++ supports multiple inheritance which may lead to ambiguity.
class left {
public:
void foo();
};
class right {
public:
void foo();
};
class bottom : public left, public right {
public:
void foo()
{
//base::foo();// ambiguous
left::foo();
right::foo();
// and when foo() is not called for 'this':
bottom b;
b.left::foo(); // calls b.foo() from 'left'
b.right::foo(); // call b.foo() from 'right'
}
};
Incidentally, you can't derive directly from the same class twice since there will be no way to refer to one of the base classes over the other.
class bottom : public left, public left { // Illegal
};
Given a parent class named Parent and a child class named Child, you can do something like this:
class Parent {
public:
virtual void print(int x);
};
class Child : public Parent {
void print(int x) override;
};
void Parent::print(int x) {
// some default behavior
}
void Child::print(int x) {
// use Parent's print method; implicitly passes 'this' to Parent::print
Parent::print(x);
}
Note that Parent is the class's actual name and not a keyword.
If your base class is called Base, and your function is called FooBar() you can call it directly using Base::FooBar()
void Base::FooBar()
{
printf("in Base\n");
}
void ChildOfBase::FooBar()
{
Base::FooBar();
}
In MSVC there is a Microsoft specific keyword for that: __super
MSDN:
Allows you to explicitly state that you are calling a base-class implementation for a function that you are overriding.
// deriv_super.cpp
// compile with: /c
struct B1 {
void mf(int) {}
};
struct B2 {
void mf(short) {}
void mf(char) {}
};
struct D : B1, B2 {
void mf(short) {
__super::mf(1); // Calls B1::mf(int)
__super::mf('s'); // Calls B2::mf(char)
}
};
If access modifier of base class member function is protected OR public, you can do call member function of base class from derived class.
Call to the base class non-virtual and virtual member function from derived member function can be made.
Please refer the program.
#include<iostream>
using namespace std;
class Parent
{
protected:
virtual void fun(int i)
{
cout<<"Parent::fun functionality write here"<<endl;
}
void fun1(int i)
{
cout<<"Parent::fun1 functionality write here"<<endl;
}
void fun2()
{
cout<<"Parent::fun3 functionality write here"<<endl;
}
};
class Child:public Parent
{
public:
virtual void fun(int i)
{
cout<<"Child::fun partial functionality write here"<<endl;
Parent::fun(++i);
Parent::fun2();
}
void fun1(int i)
{
cout<<"Child::fun1 partial functionality write here"<<endl;
Parent::fun1(++i);
}
};
int main()
{
Child d1;
d1.fun(1);
d1.fun1(2);
return 0;
}
Output:
$ g++ base_function_call_from_derived.cpp
$ ./a.out
Child::fun partial functionality write here
Parent::fun functionality write here
Parent::fun3 functionality write here
Child::fun1 partial functionality write here
Parent::fun1 functionality write here
Call the parent method with the parent scope resolution operator.
Parent::method()
class Primate {
public:
void whatAmI(){
cout << "I am of Primate order";
}
};
class Human : public Primate{
public:
void whatAmI(){
cout << "I am of Human species";
}
void whatIsMyOrder(){
Primate::whatAmI(); // <-- SCOPE RESOLUTION OPERATOR
}
};
struct a{
int x;
struct son{
a* _parent;
void test(){
_parent->x=1; //success
}
}_son;
}_a;
int main(){
_a._son._parent=&_a;
_a._son.test();
}
Reference example.
I obtain a error: 'func' does not name a type when a member function func of a class B attempts to return a class C:
class A {
public:
class B {
public:
C func() const {
...
}
private:
friend class A;
}
class C {
public:
...
private:
friend class A;
}
private:
...
}
Whereas, if func is a member function of A, then the following does not produce this error:
class A {
public:
class B {
public:
...
private:
friend class A;
}
C func() const {
...
}
class C {
public:
...
private:
friend class A;
}
private:
...
}
How can I fix it to make the first version work?
I found a great example here.
Define class C "above" class B, or forward declare it.
parent class
class Test {
public:
Test(){};
virtual ~Test(){};
void print() { cout<<1<<endl;};
};
sub class .h define
class TestSub: public Test {
public:
TestSub();
virtual ~TestSub();
};
sub class .cpp implements
#include "TestSub.h"
TestSub::TestSub() {
}
TestSub::~TestSub() {
}
void TestSub::print(){
cout<<2<<endl;
}
int main(){
TestSub *t=new TestSub();
t->print();
}
why:
..\src\TestSub.cpp:17:21: error: no 'void TestSub::print()' member function declared in class 'TestSub'
You have 2 errors:
First you have to declare you function in TestSub as : void print();
Second you have to specify a return type for you implementation, C++ do not accept default return type such as C, so you must convert your implementation to void TestSub::print() {...}
print() funciton is not declared in TestSub class.
class TestSub: public Test {
public:
TestSub();
void print(); // add declaration.
virtual ~TestSub();
};
I guess you also intended to make Test::print virtual?
class Test {
public:
Test(){}
virtual ~Test(){}
virtual void print() { std::cout << 1 << std::endl;}
};
If you don't specify the return type C defaults to int as return type of a function. Which doesn't match the void return type of the declaration in the class.