3.6 * vector_a; why can I not implement this binary operator as a member operator of a class Vector?

class cycle
{
 cycle();
~cycle;
pedal();
};

class bicycle
{
bicycle();
~cycle;
pedal();
};

bicycle *bikeptr = new bicycle;
cycle cycleptr=dynamic_cast <cycle>bikeptr;
cycleptr->pedal();

Okay, here are the questions I have...
which pedal function gets called, cycle or bicycle?

If I want to make sure the cycle version gets called, how do I do that? Would it be similar for bicycle, just change the names?

If I want pedal to be a pure virtual function, how do I do that?

How do I call the "cycle" pedal in main?

Can it be called from bicycle also?

Sorry about all the questions, but virtuals have me kind of lost and I'm trying to make sense of it

Recommended Answers

All 14 Replies

For your first question, why not make a class that extends from the vector class and overload the binary operator in your extended class to do the scalar-to-vector multiplication you want?

Also, because your cycle method in your base class isn't virtual, it will call its own method of cycle, not bicycles.

If you want polymorphic behavior, where your base class only uses one method that executes data of an extended classes method of the same method name you'll have to mark your base class' method to virtual.

Alex, thanks for responding. First, I'm more than willing to explore doing it your way with the vector, but can you tell me why it doesn't work the way it is now?

Now if I understand what you're saying, it will call the cycle version of pedal for my first virtual question? I thought it would call bicycle's version.

In question 2, I thought maybe putting the virtual keyword in front of pedal would "force" it to use cycle's pedal function, but I don't know how to do that for bicycle.

In question three, again I thought maybe this was done in the cycle class by putting virtual before pedal, and "=0" after the ().

and then the question still remains, how is it called in main?

Alex, thanks for responding. First, I'm more than willing to explore doing it your way with the vector, but can you tell me why it doesn't work the way it is now?

Now if I understand what you're saying, it will call the cycle version of pedal for my first virtual question? I thought it would call bicycle's version.

In question 2, I thought maybe putting the virtual keyword in front of pedal would "force" it to use cycle's pedal function, but I don't know how to do that for bicycle.

In question three, again I thought maybe this was done in the cycle class by putting virtual before pedal, and "=0" after the ().

and then the question still remains, how is it called in main?

I'm not too sure about the vector class, but it could be that vector doesn't have an operator defined to multiply all components by a scalar. I'm aware of the initialization constructor but not of this operator (Im still new to c++ but I know at least this much =P ).

And about the virtual function... before looming over the keyword, consider what's happening between your classes.

Your Base class is its own object. The Derived class is an instance of Base and has additional data. The Base class is like a father who knows he has children but doesn't know where they are, and won't acknowledge them even if you told Base class they were its children. Derived class, however, knows very much where it was derived from (Base) so it knows all of Base's functions.

When marking Base's method virtual, you are now telling Base that he has a child that has a method like his... so he will respect that and he will fire the childs method (or data) instead of his own when the Base's method is called. --That is, when you upcast the Derived into a Base pointer... not just all the time when you create a new Base object >_<

However, I do not expect the behavior to be the same if you mark the Derived child's method to be virtual. Base class would then not know of Derived class at all and would most likely not be influenced by Derived class's marking of a virtual function.

Okay, so as written, cycle's version of pedal is used. If I put the word virtual in front of it, then bicycle's version is used?

Okay, so as written, cycle's version of pedal is used. If I put the word virtual in front of it, then bicycle's version is used?

Correct.

To test this first run the program after putting something along the lines like--

cout << "I am BASE" << endl;

in your base's method and then

cout << "I'm a DERIVED" << endl;

in your derived method to understand this.

okay, I think I got that, but is there a way to make sure I call pedal from the cycle class everytime no matter how many objects I create?

would it be by using cycle:: pedal(); ?

There still remains the question of how I call it from main (a running theme with me if you've seen any of my other posts)

> 3.6 * vector_a; why can I not implement this binary operator as a member operator of a class Vector?
you can, if the class Vector is your own class.
if not ( for example for standard containers ), you can overload this operator as a free function (not a member function). eg.

#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>

template < typename T, typename A,
           template< typename U, typename V > class container >
container<T,A> operator* ( const T& n,
                           const container<T,A>& cntr )
{
  container<T,A> result ;
  std::transform( cntr.begin(), cntr.end(),
                  std::back_inserter(result),
                  std::bind1st( std::multiplies<T>(), n ) ) ;
  return result ;
}

template < typename T, typename A,
           template< typename U, typename V > class container >
inline container<T,A> operator* ( const container<T,A>& cntr,
                                  const T& n )
{ return n * cntr ; }

int main()
{
  std::vector<double> v1(10,3.4) ;
  std::vector<double> v2 = 3.6 * v1 ;
}

> If I want pedal to be a pure virtual function, how do I do that?
put an = 0 ; at the end of the function declaration. and not in the definition (if you want to define it; it need not be defined).

> but virtuals have me kind of lost virtual means: the function is to be called based on the run-time type of the object, not the compile-time type of the variable. eg.

#include <iostream>
#include <typeinfo>

struct base_class
{
  virtual void virtual_foo() = 0 ; // pure

  void nonvirtual_bar()
  { std::cout << "base_class::nonvirtual_bar\n" ; }

  virtual ~base_class() {}
};

void base_class::virtual_foo()
{ std::cout << "base_class::virtual_foo\n" ; }

void function( base_class* pointer_to_object )
{
  std::cout << "compile-time type of pointer is "
            << typeid( pointer_to_object ).name() << '\n' ;
  std::cout << "run-time type of object is "
            << typeid( *pointer_to_object ).name() << '\n' ;

  // virtual, dispach based on run-time type of object
  pointer_to_object->virtual_foo() ;

  // not virtual, dispach based on compile-time type of pointer
  pointer_to_object->nonvirtual_bar() ;
}

int main()
{
  struct derived_class : base_class
  {
    virtual void virtual_foo() // override
    { std::cout << "derived_class::virtual_foo\n" ; }

    void nonvirtual_bar()
    { std::cout << "derived_class::nonvirtual_bar\n" ; }
  };

  base_class* pointer = new derived_class ;
  function( pointer ) ;
}

note: for virtual functions to work, you need to derive bicycle from cycle.
eg. class bicycle : public cycle { /* ... */ }; and then, bicycle* pbc = new bicycle ; cycle* pc = pbc ; etc.

3.6 * vector_a; why can I not implement this binary operator as a member operator of a class Vector?

class cycle
{
 cycle();
~cycle;
pedal();
};

class bicycle
{
bicycle();
~cycle;
pedal();
};

bicycle *bikeptr = new bicycle;
cycle cycleptr=dynamic_cast <cycle>bikeptr;
cycleptr->pedal();

Your pointer is given a valid bicycle address (and of course the potential to store information big enough for a bicycle).

Now you're trying to cast it into an instantiated variable of cycle, which I am not entirely sure will work out too well. Instead you may want to assign the address of bikeptr to a cycleptr--

cycle *cycleptr = reinterpret_cast<cycle*>(bikeptr);
cycleptr->pedal();

//and yes, this is in main =p

If I'm getting this, the call from main would look something like

bicycle * bicycleptr = new bicycle;
pedal (bicycleptr);

Would that be correct? (according to Vij's post)

Alex, in your post why do you not think the downcast would work?

If I'm getting this, the call from main would look something like

cycle * cycleptr = new bicycle;
pedal (cycleptr);

Would that be correct?

No, because your namespace has no method named pedal defined and also the method pedal in your base and derived classes has no parameters.

replace pedal(cycleptr) with either--

cycleptr->pedal();

//or

(*cycleptr).pedal();

ahhh I see.

Now if I wanted to call pedal from cycle, but within bicycle, I think I can do it by just putting cycle::pedal(); in bicycle's member function pedal. Is there another way to do it? (I did this in a door class with a door open member function, but I'm told it can be done another way)

ahhh I see.

Now if I wanted to call pedal from cycle, but within bicycle, I think I can do it by just putting cycle::pedal(); in bicycle's member function pedal. Is there another way to do it? (I did this in a door class with a door open member function, but I'm told it can be done another way)

Indeed, within the class you can use cycle::pedal(), but I think you can also use the this modifier to point to the base object--

this->pedal()

--though they both should mean the same thing. Using one or the other is entirely up to you, but I prefer the Base::functoname() method much better since it's more intuitive imo.

A huge thanks Alex, I think I'm starting to understand it. The whole class hierarchy thing wasn't too hard, but when the instructor started talkin virtuals, pure virtuals and virtual pointers, I got a bit overwhelmed. Now I just have to figure out my vector lab, but I think that will be tomorrow...lol..getting late here. Again, thanks tremendously for your help and patience

ahhh I see.

Now if I wanted to call pedal from cycle, but within bicycle, I think I can do it by just putting cycle::pedal(); in bicycle's member function pedal. Is there another way to do it? (I did this in a door class with a door open member function, but I'm told it can be done another way)

why not just call

pedal()

what is the difference?

if pedal is a virtual function in "cycle", then both will accomplish the same thing

but I think you can also use the this modifier to point to the base object--

this->pedal()

this is identical to just

pedal()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.