It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
class A{};
class B : A{};
void func(A* p)
{
B* p2 = p; // Error
}
Your code has several oddities.
You use private inheritance. In private inheritance you will not be able to convert to a derived class ever when you are not inside the class scope itself.
Even if you would inherit publicly, you will need at least one virtual function (and that should be the destructor) in the base class to use dynamic_cast.
Chances are you are doing something wrong when you need a lot of down-casts. You should probably rethink your design or usage of the provided API.
Typically, things would look like this:
class A {
public:
virtual ~A() {}
};
class Derived : public A {
};
void func(A* a) {
if(Derived* d = dynamic_cast<Derived*>(a)) {
// yeah, a is of type derived
} else {
// a is not of type Derived
}
}
is-a relationship is implemented by public inheritance. as you are inheriting it privately this is association relationship which is not is-a. so B is not an A. So you cannot store A in B or A cannot become an B
and dynamic_cast will not work as source type is not polymorphic
neither would static_cast work as ‘A’ is an inaccessible base of ‘B’
To make an is-a relationship you need to do class B: public A{}
For classes private inheritance is used by default.
Related
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
In C++, I want to be able to call a method in the same class without creating an object of the whole class. The class is huge and I do not want to create a huge memory location for an object. I am used to programming in C#.
In C# I could do this
class test()
{
private void A()
{
B();
}
private void B()
{
doSomething;
}
}
in C++ I am under the impression I have to do.
class test()
{
public:
static void A();
void B();
};
void test::A()
{
test t;
t.B();
}
void test::B()
{
doSomething;
}
}
I do not want to make B() static nor do I want to create and object of test because in reality my class is a lot larger than this, and creating a object of the class would use memory that I do not want to.
Is there a way I can accomplish what I could in C# in C++?
No. If B needs an object, you have to give it an object. If B doesn't need an object, declare it static. C# is no different -- in your example, A is not static so the object already exists.
static void A();
void B();
You cannot use static function to call non-static one at all.
Solution:
Mark B as static too (if it doesn't depend on current object) and thus you don't have to creat a new object. Else I think A should be non-static.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
A question about C++ programming.
Can you do in C++ something like this:
Lecture le;
Carriage ca = le;
No casting, just writing like that. The problem is, when I am trying to invoke a method which belongs to Lecture class the methods is underlined in red.
ca.runIt();
I am not quite sure if I understood the specification of my task, but there is given this snippet of code. Best regards
Can you do in C++ something like this:
Yes.
struct Lecture {
};
struct Carriage {
Carriage(const Lecture&) {
}
void runIt() {
}
};
int main() {
Lecture le;
Carriage ca = le;
ca.runIt();
}
The problem is, when I am trying to invoke a method which belongs to Lecture class the methods is underlined in red.
Of course. ca isn't a Lecture. ca is a Carriage. You can only invoke Carriage methods on ca.
Let's break it down, from the general case to the most specific.
If you have some arbitrary class A and some other arbitrary class B, the statement:
A a;
B b = a;
is generally not going to work. It will certainly not work by itself; you have to put effort into making it work.
So now, let's get specific. If B is a class derived from A, then it will also not work. If A is derived from B, it will still not work.
Why? Because A a defines an object, not a reference. It creates a value. B b = a; is an attempt to store the value a into a new value b. You cannot do that.
If A is derived from B (B is the base class), you can do this:
A a;
B &b = a;
That's legal C++, and it's meaningful too. b now refers to part of a. Specifically, the part of a that is the base class.
Note that the reverse does not work. If A were the base class, C++ would raise an error.
Now, there is one way to make the general statement work.
A a;
B b = a;
If you want this to be reasonable for a specific class B, then B must be defined as follows:
class B ... //Whatever base classes you want.
{
public:
B(const A &a);
};
The constructor that takes a const A & is a conversion constructor. It's job is to create a B object using data from an a object. Because this conversion constructor was declared without the explicit keyword, then it can be used for implicit conversions like B b = a; If it were declared with the explicit keyword, you would have to explicitly convert it: B b = B(a);.
Having a conversion constructor on a class means that any instance of A can be converted into a B. So you can pass A to a function that takes a B (either by value or by const&. Not by reference) without having to do an explicit conversion.
Note that conversion constructing an object does not allow you to call functions from A on the object B. You can only call functions on B which B defines or are defined by one of B's base classes.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am trying to modify template type given at compile time but unable to do it. Let see if you have some idea.
Lets consider we have 2 classes class A and A_test and one template class B.
Will implemented class B as it is having a function b_f() which is internaly creating an object of template class and calling public funcion A_f()/A_test_f() of class A or Class A_test.
from main, will be creating class B obj; obj.b_f();
but I want to creat an object of class A_test not class A.
Let me know if it is possible.
Basicaly I wanted to do object injection. Please let me know if it is possible.
The best solution by far is to try to rename A_test_f() to be the same as A_f().
If that proves impossible, the next thing I'd try is to specialize class B:
template<class AT>
class B {
public: b_f() {
AT m_A;
m_A.A_f();
};
template<>
class B<A_test> {
public: b_f() {
AT m_A;
m_A.A_test_f();
};
If B is too complicated, there are other things to try, but you probably want to rethink what you're doing first. If all else fails, do what I coded above here, but call it B_HELPER instead of B and then b_f() can do: B_HELPER<AT> m_A; m_A.b_f(); That way you don't have to recode all of B.
The common way to inject dependencies into templates at compile-time is through type traits. This allows customizing the templates externally through another struct or class which has specific knowledge of the class. Examples in the standard library include std::char_traits<> and std::iterator_traits<>. Boost also defines some, including boost::type_traits<>.
Traits involve defining a struct for the general case and specializing it for alternate cases when necessary.
// general case: select method named "f".
template<class T> struct b_traits
{
typedef void(T*F)();
static const F f = &T::f;
};
// template type that forwards method selection to "b_traits" struct.
template<class AT>
class B {
public: b_f() {
AT m_A;
(m_A.*(b_traits<AT>::f))();
};
class A_test { ... };
// special case: select method named "A_test_f".
template<> struct b_traits<A_test>
{
typedef void(T*F)();
static const F f = &A_test::A_test_f;
};
int main ()
{
B<A_test> b;
b.b_f(); // will invoke "A_test::A_test_f()" rather than "A_test::f()".
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
How should I get rid of the problem with object slicing in c++.
In my application if the derived class has some dynamically allocated pointer and derived class object is assigned to base class object, the behavior is memory corruption!
It depends on your design. You may have to change certain design criteria to get rid of it. One of the options is to have an overloaded operator = and copy constructor in your base class for particular derived class.
class Derived;
class Base
{
//...
private:
Base (const Derived&);
Base& operator = (const Derived&); // private and unimplemented
};
Now if you attempt to do something like following:
Derived d;
Base b;
b = d; // compiler error
it will result in compiler error.
you can't. you should solve the problem with the pointer. if you want to assign Obj2 to Obj1, override assign operator (operator=)
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I would like to get a vector/list of derived class pointers (one corresponding to each derived class from an abstract base class) given the base class name, for instance.
So to do exactly what you seems to want to do
#include <list>
class BaseObject { };
class Dinosaur : public BaseObject { };
class Hammer : public BaseObject { };
void
myFunction() {
std::list<BaseObject*> myList;
myList.push_back(new Dinosaur());
myList.push_back(new Hammer());
}
Note that the objects in the list won't free by themselves when the list will be destroyed. Either you have to do manually (Iterating over the list and calling delete), either look on something a bit complex if you are a C++ beginner, auto_ptr, and the magic world of the smart pointers ^^
You can't get a pointer to a class. A class is just a specification for an object. You only have something to point to once an object is created by instantiating the class.
If you have the following classes:
class FooBase {};
class DerivedFoo : public FooBase {};
class MoreDerivedFoo : public DerivedFoo {};
you can then create an object of type MoreDerivedFoo and point to it using a pointer of any of those types.
MoreDerivedFoo mdf = new MoreDerivedFoo();
FooBase* p1 = &mdf;
DerivedFoo* p2 = &mdf;
MoreDerivedFoo* p3 = &mdf;
Obviously each of these pointers will contain the same memory address.