C++ Method Only Visible When Object Cast to Base Class

C++ method only visible when object cast to base class?

You have shadowed a method. For example:

struct base
{
void method(int);
void method(float);
};

struct derived : base
{
void method(int);
// base::method(int) is not visible.
// base::method(float) is not visible.
};

You can fix this with a using directive:

class derived : public base
{
using base::method; // bring all of them in.

void method(int);
// base::method(int) is not visible.
// base::method(float) is visible.
};

Since you seem insistent about the number of parameters, I'll address that. That doesn't change anything. Observe:

struct base
{
void method(int){}
};

struct derived : base
{
void method(int,int){}
// method(int) is not visible.
};

struct derived_fixed : base
{
using base::method;
void method(int,int){}
};

int main(void)
{
{
derived d;

d.method(1, 2); // will compile
d.method(3); // will NOT compile
}
{
derived_fixed d;

d.method(1, 2); // will compile
d.method(3); // will compile
}
}

It will still be shadowed regardless of parameters or return types; it's simply the name that shadows. using base::<x>; will bring all of base's "<x>" methods into visibility.

Objective-C cast baseclass object into specific class

Check NSObject's method isKindOfClass:(Class)c
You would do this:

-(void)doSomething:(A *)param
{
//do some stuff
if([param isKindOfClass:[B class]])
{
//do stuff with B (cast will be required to avoid warnings!)
B *castedB = (B *)param;
//...
}
else if ([param isKindOfClass:[C class]])
{
//do stuff with C
C *castedC = (C *)param;
//...
}
}

Hope this help!

Casting Deriving Class as Base Class

I know that the new keyword will override the method implementation in the deriving class

No. It does not override the base class's method. It declares a new, independent method, that's just named the same and has the same signature. The effect is it hide the same-signature method declared in the base class, effectively complicating the invocation of the same-signature method declared in the base class.

In your example there are no 'type conversions' whatsoever. Think of a type cast as providing a specific view of the instance—exposing the specific part of the class's contract to the user. It's nothing more, nothing less.

Example:

// instance of DerivedClass exposing its full contract via the 'dc' variable
DerivedClass dc = new DerivedClass();

// the same instance of DerivedClass exposing its contract limited to what's declared in BaseClass
BaseClass bc = dc;

// calling Method2 as newly declared in DerivedClass
dc.Method2();

// calling Method2 as declared in BaseClass—the following two lines are equivalent
bc.Method2();
((BaseClass)dc).Method2();

why can't I access this method via inheritance?

Because Bar::stuff hides Foo::stuff (only the name matters when overload resolution is performed, parameters are ignored).

You can :

  • Bring it into sope with a using declaration
  • Or alternatively, explicitly qualify the call e.g. b.Foo::stuff(3);.

Note :

  • main() must return an int.

#include <iostream>

class Foo
{
public:
int a;
void stuff(int a){ std::cout << a << std::endl; }
};

class Bar : public Foo
{
public:
using Foo::stuff;
protected:
void stuff() { std::cout << "hello world"; }
};

int main()
{
Bar b;
b.stuff(3);
}

Or :

int main()
{
Bar b;
b.Foo::stuff(3);
}

Permanently cast derived class to base

What you ask for is impossible for two reasons:

  1. ItemA.GetType() does not return the compile-time type of the variable ItemA - it returns the run-time type of the object referred to by ItemA.
  2. There's no way you could make (A)B result in a representation-changing conversion (i.e. a new A object) because user-defined conversion operators (your only hope here) cannot convert from derived to base-classes. You're just going to get a normal, safe, reference-conversion.

That aside, what you ask for is very strange; one would think you're trying really hard to violate Liskov's substiution principle. There's almost certainly a serious design-flaw here that you should address.

If you still want to do this; you could write a method that manually constructs an A from a B by newing up an A and then copying data over. This might exist as a ToA()
instance-method on B.

If you characterized this problem as "How do I construct an A from an existing A?", it makes a lot more sense: create a copy-constructor on A, whose declaration looks like public A(A a){...}, which is agnostic to subclass-specific details. This gives you a general means to create an A from an existing instance of A or one of its subclasses.

Visibility of properties in derived classes (C#)

Because you are assigning your derived class to a property with the type of the base class only the methods and properties of the base class will be available. And this makes sense since you could have assigned any instance of a class that derives from the base class - so any derived methods cannot be used in this context.

This is one of the OOP principles - your derived class instances may be used as an instance of a base class (but not the other way round)

Edit:

To elaborate on the solution proposed by @sll to cast to a particular derived class type: Don't do it! It is a workaround but not in the interest of the overall design.

If you have to cast to a derived type then you are violating the Liskov substitution principle meaning that any derived type should be usable in place of the base type - that's clearly not the case if you need a specific cast.

Rethink your design - do you really need a property with the base class type and if so are the methods currently only in one particular derived type better off being in the base type as well?

C++, how to cast derived class to protected base?

With this, you're telling the compiler that you can't implicitly convert a Line to an Object:

class Line : protected Object {
};

But it seems to me that you want to do this, and also that you should do this. So make the inheritance public. This is a design question.

Don't make the inheritance protected just to keep methods in the base class protected.

One other option is to implement the cast operator in Line:

class Line : protected Object 
{
public:
operator Object&();
};

and call the function like so:

a.Add(Line());

instead of

a.Add(new Line());

You can't implicitly cast pointers in this situation. However I suggest changing the inheritance type.

c++ design: cast from base to derived class with no extra data members

Here is why I would not use this technique:

  1. It is a violation of the Standard and causes the behavior to be undefined. It is probably true that this works nearly all the time, but you can't rule out problems in the future. Compilers have been seen to make use of undefined behavior in optimizations, much to the disadvantage of the unsuspecting programmer. And you can't predict when and under what circumstances this will happen.

  2. You can't guarantee that neither you nor a team mate will ever add some data members to the derived type. Your class hierarchy will grow and more code will be added over time; at some point it may not be obvious to you or another programmer that adding an innocent data member to the derived type (even temporarily, perhaps for some debugging purpose) can spell disaster.

  3. There are clean and legal alternatives, for example using wrappers based on references:

    #include <iostream>

    struct Elem
    { };

    struct ElemWrapper
    {
    Elem &elem_;

    ElemWrapper(Elem &elem) : elem_(elem)
    { }
    };

    struct ElemWrapper1 : ElemWrapper
    {
    using ElemWrapper::ElemWrapper;

    void foo()
    { std::cout << "foo1" << std::endl; }
    };

    struct ElemWrapper2 : ElemWrapper
    {
    using ElemWrapper::ElemWrapper;

    void foo()
    { std::cout << "foo2" << std::endl; }
    };

    int main()
    {
    Elem e;

    ElemWrapper1(e).foo();

    return 0;
    }

Can I cast a derived class to a private base class, using C-style cast?

Yes you can: §5.4/7 of the standard:

... the following static_cast and reinterpret_cast operations
(optionally followed by a const_cast operation) may be performed using
the cast notation of explicit type conversion, even if the base class
type is not accessible:

a pointer to an object of derived class type or an lvalue of derived
class type may be explicitly converted to a pointer or reference to an
unambiguous base class type, respectively;

But try not to as it defeats the purpose of private inheritance.



Related Topics



Leave a reply



Submit