can s.one please help me to understand what I'm doing wrong in this process, so that I don't have access to my vector "vect"
#include <iostream>
#include <vector>
class A
{
private :
public :
A() {}
};
class B
{
private :
std::vector<A*> vect;
public :
B() {}
void func(){
std::cout << vect.size() <<std::endl;
}
};
class C
{
private :
B* b ;
public :
C() { }
void func (){
b->func();
}
};
int main (){
C c;
c.func();
return 0 ;
}
I expect to get "0" as an output but it seems like the vector hasn't been acceded so I get unrelevant number "17591314330723" !!!!
class C
{
private :
B* b ;
public :
C() { }
void func (){
b->func();
}
};
Looking at just this class; you can see that b is never assigned. In addition to that it's a pointer. This means that when you call b->func() you're trying to call func() on a random piece of memory. This is undefined behavior and you're unlucky that it didn't just crash (since it hides the problem).
Your options are to either assign b to a value; which I'm not going to explain how to do; your C++ book should cover that; or to change it to be not a pointer; (ie remove the *) which will create a new B for you when you create a C.
Related
I'm learning C++ OOP. I don't understand a principle, and I don't know what to google to find an answer.
If I have this:
#include <iostream>
class A
{
public:
int a;
A() : a(1){}
};
class B : virtual public A
{
public:
B() {this->a = 2;}
};
class C : virtual public A
{
public:
C() {this->a = 3;}
};
class D : public B, public C
{
public:
D() {this->a = B::a;}
};
int main()
{
D test;
std::cout << test.a << std::endl;
}
I expect the output to be 2 since I want the value of the inherited B class in the D class. It seems to me like the value of the C class is taken, because that constructor gets called last and overwrites the B::a value, is that right?
How would I go about getting values from the B class inside the D class?
//In file1.hpp
class A
{
protected:
class B
{
public:
B () {};
};
};
// In file2.hpp
class C
{
public:
void getValue()
{
D obj; ---- error: no matching function for call to D
printf("%d\n",obj.c);
}
class D : public A::B
{
friend class C; -- I tried writing this but still no luck.
public:
D(int a, int b) : c(a), d(b) {}
virtual ~D() {}
//something
private:
int c; int d;
};
class E : public D
{
E() : D(1,2) {}
virtual ~E() {}
};
}
int main()
{
C::E obj;
}
In the public function, getValue I want to access the private member variables of the class D which are (c and d). How can I do that? I tried putting "friend class C" inside class D and then tried creating an object of class D inside getValue function but instead of getting a value like c=5 or d=6, I always get 0.
If I print the value in the following area, I get the correct value. I won't be able to show you how getValue is called but just imagine that it is called somehow. I just need to print c,d in that.
D(int a, int b)
: c(a), d(b) {};
EDIT: At the time of instantiation in getValue, I do something like this
D obj; --- error: no matching function for call to D
Let take the following example:
#include <iostream>
//In file1.hpp
class A
{
protected:
class B
{
public:
B () = default;
};
friend class C; // <-- bad idea
};
// In file2.hpp
class C
{
public:
void getValue()
{
// Creating an object E?
E objE;
// Access c and d
std::cout << "c:" << objE.c << ", d:" << objE.d << std::endl;
}
class D : public A::B // <-- bad idea?
{
public:
D(int a, int b): c(a), d(b) {}
virtual ~D() {}
//something
private:
int c; // dangerous to not initialize basic types
int d;
friend class C; // <-- bad idea
};
class E : public D
{
public:
E() : D(1,2) {}
virtual ~E() {}
};
};
int main()
{
C objC;
objC.getValue();
}
( you can run it here: https://onlinegdb.com/hNfm7Pvg0f )
First is, to have an instance of E to access in C::getValue, so I instantiated an object.
private and protected indicate that those properties and methods are not available publicly (encapsulation) and that is exactly what you are trying to do. You can make exceptions with friend keyword, but that is rarely a good idea (I probably use it twice in my 20 years carrier). But hey! it works.
Hi I have a derived class and I want to pass the pointer of the derived class object to the base class.
I am getting segmentation fault while running the code.
#include <iostream>
using namespace std;
class A {
public:
virtual void x() = 0;
A* a;
};
class B: public A {
public:
B(A* x) {
a = x;
}
void x () {}
};
class C: public B {
public:
C() : B(new C) { }
};
int main() {
C c;
return 0;
}
Can someone help me suggest a way to achieve this or help me in fixing the code.
I believe you want to pass a pointer to current object. This is what this is for.
C() : B(this) { }
I have 3 classes namely
class A;
class B;
class C : public B {
};
Now i want to use some member functions in C, that have been made virtual in A and have been overridden in B. When I try to access a member of A from C it gives an error saying that C is not a direct base class of A.
What should I do? Should I write that piece of code again?
I searched other sites and got confused answers which ruined my concepts of inheritance, so please give a descriptive but clear answer
Is this what you mean?
class A {
public:
virtual int f() { return 42; }
};
class B : public A {
public:
int f() { return 0; }
};
class C : public B {
public:
int g() { return f(); }
};
There is nothing special to do.
void C::f() { return A::f(); }
Won't this be enough?
Your question isn't very clear. Are you asking how to call A's or B's version of the function? If so, you could do something like this:
#include <iostream>
struct A
{
virtual void Foo () {
std::cout << "A::Foo()" "\n" ;
}
};
struct B : public A
{
void Foo () {
std::cout << "B::Foo()" "\n" ;
}
};
struct C : public B
{
void Foo () {
std::cout << "C::Foo()" "\n" ;
}
};
int main (void)
{
C c ;
c.A::Foo () ;
c.B::Foo () ;
c.Foo () ;
A *p1 = &c ;
p1->Foo () ;
return 0 ;
}
Output:
A::Foo()
B::Foo()
C::Foo()
C::Foo()
What should I do? Should I write that piece of code again?
You can always explicitly refer to methods declared in class A as long they are visible from your inheritance protection scope:
class A {
public:
virtual void foo() {}
};
class B : public A {
public:
virtual void foo() {
// do something else
}
};
class C : public B {
public:
virtual void foo() {
// use A's implementation again
A::foo();
}
};
I'm quite new to the concept of inheritance, and to C++ too, so my problem may be really stupid...
class A {
public :
A() {}
A(string name) {name_ = name}
private :
string name_;
}
class B : public A {
public :
B() {}
B(string name, int number) {
name_ = name;
number_ = number;
}
private :
string name;
int number;
}
class C {
public :
C() {}
void addClass(int id, A* a) {
map[id] = a;
}
private :
Hash_Map<int, A*> map;
}
void main() {
C* c = new C();
for (int i = 0; i < 10; i++) {
B* b = new B("randomName", 50);
c->addClass(i, b); //1st problem
delete b; //2nd problem
}
}
1st problem : shouldn't "map" in "c" keep the attribute "number" from the class "B"? I know I put A* in parameter, but if I had several class that derived from A, how should I do it?
2nd problem : All of my attributes in "map" seem to get random values when I delete "b". I'm guessing the problem is that I need to copy "b" into a new object, but how can I do it if I have "A*" as my addClass() parameter? My pointer b seems to be converted into its parent class
EDIT : had to change several things in my code that I forgot...
Bunch of problems:
1) No initializing members within a class declaration! (Your edit fixed this)
class B : public A {
public :
B() : name("A"), number(0) {} // initialize in constructor. that's what they are for!
private :
string name;
int number;
}
(Repeat that for A's declaration as well)
2)
You're storing a copy of the pointer to A (that was passed in as argument to addClass)in your map, not the actual object.
So, your map holds: 100 -> pointer to b
Then you delete whatever b points to. What would you think map[100] contains now?
A pointer to garbage! So, don't delete the pointer outside! Let C take care of it.
3) (My previous answer had a glaring error and someone voted it up. So, I'll keep the earlier part and point out my mistake)
Don't use pointers unless you need to. Save yourself some work. Go play the guitar or read some of Herb Sutter's articles!
void main() {
// don't use pointers and require that you delete them (unless you need to)
B b; // default constructor is called automatically. it is destroyed for you, by the compiler
// at the end of its scope (in this case, closing brace of main() )
C c;
c.addClass(100, b);
}
Let's fix C too. Can we get rid of those nasty pointers?
class C {
public :
C() {}
void addClass(const int id, const A a) { // use const, its a good habit!
map[id] = a;
}
private :
Hash_Map<int id, A a> map;
}
Now, what's wrong with this? Not just extra copies; when you pass b as argument to addClass by value, the compiler is gonna copy the A portion of b! So, we lostb`'s data (and overrides)!
So, we absolutely have to use pointers (references are dangerous, since they're deleted at scope exit).
What's important is that you make C owns the deletion.
So your code would now look like:
class C {
public :
C() {}
~C() {
for(pair<int, A*>& p : map) // C++11 syntax, yay!
delete p.second; // here's where you clean up. not in main.
}
void addClass(const int id, const A* a) {
map[id] = a;
}
private :
Hash_Map<int, A*> map;
}
void main() {
B* b = new B(); // back to square 1!
C c;
c.addClass(100, &b);
} // no memory leaks
But I hate taking care of deletion you say.. Fear not, we have shared_ptr!
#include <memory>
using namespace std;
typedef shared_ptr<A> Aptr;
class C {
public :
C() {}
~C() {
cout << "Drinking a beer coz i use shared_ptr";
}
void addClass(const int id, Aptr& a) {
map[id] = a;
}
private :
Hash_Map<int, Aptr> map;
}
void main() {
Aptr b(new B());
C c;
c.addClass(100, b);
} // still no memory leaks
Hope that helps.