Forward declaration of derived class - c++

I have some code like that:
class Class1 {
// some code here
Class2 inverse() {
// some code here
}
};
class Class2 : public Class1 {
// some code here
};
And I got an error that Class2 is unknown in function inverse. Can I declare that class and how?

You can forward declare Class2 before Class1. And then you'll have to separate your inverse function declaration from definition. So you should define its after Class2 is defined:
class Class2;
class Class1 {
// some code here
Class2 inverse();
};
class Class2: public Class1 {
// some code here
};
Class2 Class1::inverse()
{
return Class2();
}
But, honestly, it is bad design.

Class2 is not defined when you reach Class2 inverse() so even forward declaring would not completely solve that issue. However you can do two things. Either return a pointer or a reference to Class2
class Class2;
^^^^^^^^^^^^
class Class1 {
Class2& inverse() {
// ^^^ or possibly Class2*
//
}
};
class Class2: public Class1 {
}
Or defined inverse after Class2 have been completely defined
class Class2;
class Class1 {
Class2 inverse();
};
class Class2: public Class1 {
//
}
Class2 Class1::inverse() {
//
}
I would go with the second option if possible.

Related

What's the preferred way to instantiate one class in another?

Pretty basic question. Has to do with design preference but I think there are some caveats that I'm missing.
I want to have an instance of some class inside another class. The way I see it, I have 3 options:
Have the object class2 inside class1 as I have it below. This means it gets constructed when an instance of class1 gets constructed. My issue here is that it may need a default and/or copy constructor? When I instantiate a class1 object below, does it construct class2_inst(args) using that constructor? Or is class2_inst already created with some default constructor and the line class2_inst(args) simply copies an anonymous class2 object?
class class2 {
public class2(args) {
...
}
}
class class1 {
protected class2 class2_inst;
public class1(args) : class2_inst(args) {
...
}
}
I can have a pointer to class2:
class class2 {
public class2(args) {
...
}
}
class class1 {
protected class2* class2_inst;
public class1(args) {
class2_inst = new class2(args);
...
}
}
This has the advantage that class2 isn't instantiated until I explicitly call the new operator.
Then there's using a reference instead of a pointer:
class class2 {
public class2(args) {
...
}
}
class class1 {
protected class2& class2_inst;
public class1(args) {
class2_inst = new class2(args);
...
}
}
I want class2_inst's life-time to match that of class1. No funny business with having class2_inst living outside of class1. So references may be the way to go.
Of the 3 methods, which is everyone's preferred way, and why?
Your examples are a bit backwards. I think you meant this instead:
class class2 {
public:
class2(args) {
...
}
};
class class1 {
protected:
class2 class2_inst;
public:
class1(args) : class2_inst(args) {
...
}
};
class class2 {
public:
class2(args) {
...
}
};
class class1 {
protected:
class2* class2_inst;
public:
class1(args) {
class2_inst = new class2(args);
...
}
};
class class2 {
public:
class2(args) {
...
}
};
class class1 {
protected:
class2& class2_inst;
public:
class1(args) {
class2_inst = new class2(args);
...
}
};
Now, that being said:
Example 1 will work nicely for what you want, and is the preferred way to go: "I want class2_inst's life-time to match that of class1. No funny business with having class2_inst living outside of class1." And to answer your question - yes, class2_inst(args) will construct the class2_inst member directly, not default-construct it and then copy an anonymous class2 object into it. See Constructors and member initializer lists.
Example 2 will also work, but to make it work correctly, you need to add a destructor to class1 to delete the new'ed class2 object, and you need to also add copy/move constructors and copy/move assignment operators to class1 to copy/move class2 objects properly, per the Rule of 3/5/0.
class class2 {
public:
class2(args) {
...
}
};
class class1 {
protected:
class2* class2_inst;
public:
class1(args) {
class2_inst = new class2(args);
...
}
class1(const class1 &src) {
class2_inst = new class2(*(src.class2_inst));
...
}
class1(class1 &&src) {
class2_inst = src.class2_inst;
src.class2_inst = nullptr;
...
}
~class1(args) {
delete class2_inst;
}
class1& operator=(const class1 &rhs) {
if (this != &rhs) {
class1 tmp(rhs);
std::swap(class2_inst, tmp.class2_inst);
}
return *this;
}
class1& operator=(class1 &&rhs) {
class1 tmp(std::move(rhs));
std::swap(class2_inst, tmp.class2_inst);
return *this;
}
};
You get all of that functionality for free in Example 1, as the compiler will auto-generate those extra methods for you. Yes, there are valid cases where it makes more sense to use pointers for members, but this example is not one of them.
Example 3 is simply not valid. You can't assign an object pointer to an object reference. And why would you think "references may be the way to go"? They are not, in this case.
So, in a nutshell, you should prefer value sematics whenever possible, but use pointer/reference semantics when needed.

Access protected data members of the base class from the derived class

I have a base class and the derived class. I need to access the protected member of the base class in the derived class. However, Eclipse does not allow me to access the data member as if it were a member of a derived class without caring that it was inherited. How do I do that?
class BaseClass {
protected:
static int a;
int b;
}
class DerivedClass: public BaseClass {
void SomeMethod {
a=10; // cannot resolve symbol
b=10; // cannot resolve symbol
BaseClass::a=10; //does not complain
BaseClass::b=10; //does not complain
}
}
I couldn't completely understand your question, but fixing the syntax errors, the following should work:
class BaseClass {
protected:
static int a;
int b;
}; // <-- Missing semicolon
int BaseClass::a = 0; // Define static member
class DerivedClass: public BaseClass {
void SomeMethod() { // <-- Missing ()
a=10;
b=10;
}
};// <-- Missing semicolon

How do I instantiate an object inside of a C++ class?

For C++ learning purposes, I have the files class1.h, class1.cpp, class2.h and class2.cpp. I would like to instantiate an object named class1Obj inside class2. Where and how do I instantiate this object? Do I instantiate classObj inside the class2 constructor?
In the past I have created a pointer to a class, which worked well for that time, but I think a pointer is not the route I should take this time because the classObj will only be used inside class2.
class class1
{
//...
};
class class2
{
class1 member;
//...
};
In class2 ctor, you can initialize member in the constructor initialization list.
class2::class2(...)
: member(...)
{
//...
}
Well how did you create a pointer in the past? Presumably, you did something like this:
class class2
{
public:
class2()
{
class1Pointer = new class1();
}
// Destructor, copy constructor/assignment, etc...
private:
class1* class1Pointer;
};
Now you want to do exactly the same but this time you don't want a pointer to class1, you want a class1 itself:
class class2
{
public:
class2() {}
// Destructor, copy constructor/assignment, etc...
private:
class1 class1Obj;
};
The object will be default initialized when your class2 object is created. If your class1 constructor should take some arguments, use an initialization list:
class class2
{
public:
class2() : class1Obj(1, 2, 3) {}
// Destructor, copy constructor/assignment, etc...
private:
class1 class1Obj;
};
Instantiate a class inside a class :
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(int i)
{
}
};
class Bar
{
Foo i; //<--- instantiate a class inside a class ----
public:
Bar() : i(1) //<--- instantiate a class inside a class ----
{
}
};
int main(void)
{
Bar b;
cout<<" \nPress any key to continue\n";
cin.ignore();
cin.get();
return 0;
}
It depends on your Class1. If its constructor accepts some parameters, then you must initialize it explicitly in Class2 constructor or in initialization list.
Class2 {
public:
class2() {
//Here m_class1Obj will be instantiated
m_class1Obj = Class1(/*some params*/);
}
private:
Class1 m_class1Obj;
};
Or
Class2 {
public:
class2() : m_class1Obj() {}
private:
Class1 m_class1Obj;
};

How to access a variable in an object from a member object's function

Ok, I have a class:
class class1
{
public:
class2 object2;
int a;
};
where:
class class2
{
public:
void function2();
};
Basically, I need function2 in object2 to be able to access "a." How would I go about doing this? Thanks.
class class2
{
public:
void Function2(class1& c1)
{
c1.a;
}
}
simple.

circular class member pointer?

I am not sure if I can describe the problem, but I will try my best. Here is the situation:
If I can want a class1 has a pointer as a member variable pointing to another class, class2. Meanwhile, I want class2 also has a pointer as a member variable pointing to class1. Is that possible?
class Class1
{
private:
Class2* classptr;
... ...
public:
... ...
};
class Class2
{
private:
Class1* classptr;
... ...
public:
... ...
};
It appears to me that none of Class1 and Class2 has been recognized as an identifier. I guess none of Class1 and Class2 is created. Correct me if I am wrong.
You need a forward declaration. Either:
class Class1
{
private:
class Class2* classptr;
... ...
public:
... ...
};
or:
class Class2;
class Class1
{
private:
Class2* classptr;
... ...
public:
... ...
};