can we do object Polymorphism?

Recommended Answers

All 15 Replies

Yes. C++ has inheritance as well as generic types. This gives it full objective polymorphism. Polymorphism is actually one of the things for which C++ is famous http://lmgtfy.com/?q=C%2B%2B+Polymorphism .

not that.. i know that.
i need change 1 function, using the object name, outside of functions\class's\namespaces.
just see these code:

#include <iostream>
#include <string>
#include "events.h"

using namespace std;

class test
{
    public:
    events<> Printed{[]() { ; }};
    void write(string a)
    {
        cout << a;
        Printed();
    }

};

test a;

void a.Printed=[]()
{
    cout << "\nMessage printed\n";
};

int main()
{
    a.write("hello world");
    cin.get();
    return 0;
}

i'm trying change the Printed value outside of main. but i get these error:
"error: expected initializer before '.' token"
so what i need overloading for use it without errors?
(seems that i can't overloading '::')

You cannot change a function's behaviour on an object, only on a class. To get the exact functionality you showed you would have to use a function pointer as a member of the test class:

class test
{// private:
    public:
    event<>(*Printed)();
    test()
    {
        Printed=[]{;}//I have yet to take a good look at the syntax for this
    }
};
test a;
a.Printed=[]{cout<<"\nMessage Printed\n";}

However this is not what people are usually referring to when they use polymorphism. Polymorphism is almost always used to represent the "is a" relationship where something changes. For example a square "is a" rectangle so this is proper practice for a square and rectangle class:

class Rectangle
{// private:
    int width,height;
    public:
    virtual int getArea(){return width*height;}
};
//time for polymorphism (technically here it is just inheritance)
class Square:public Rectangle
{// private:
    public:
    virtual int getArea(){return width*width;}
};

Because of the virtual label the following code would execute the following functions:

Rectangle r;
Square s;
Rectangle *rp;
Rectangle *rps=&s;//valid!
//Here width*height is called, as you would expect
r.getArea();
//Here width*width is called, as you would expect
s.getArea();
//Here, you still get width*height
rp->getArea();
//Here, since getArea was virtual, you get width*width
rps->getArea();

So basically to override a function in a new CLASS it is as easy as writing a new version of the function (virtual keyword is optional unless you deal with pointers to base classes). However overriding a function in a new OBJECT is very difficult.

commented: thanks for try +2
#include <iostream>
#include <string>
#include "events.h"

using namespace std;

class test
{
    public:
    events<>(*Printed)();
    void write(string a)
    {
        cout << a;
        Printed=[]{;};
    }

};

test a;
a.Printed=[]{cout<<"\nMessage Printed\n";})

int main()
{

    a.write("hello world");
    cin.get();
    return 0;
}

sorry i'm getting errors:(

"C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp||In member function 'void test::write(std::string)':|
C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|14|error: invalid user-defined conversion from 'test::write(std::string)::__lambda0' to 'events<> ()()' [-fpermissive]|
C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|14|note: candidate is: test::write(std::string)::__lambda0::operator void (
)()() const <near match>|
C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|14|note: no known conversion for implicit 'this' parameter from 'void ()()' to 'events<> ()()'|
C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|20|error: 'a' does not name a type|
C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|20|error: expected unqualified-id before ')' token|
||=== Build finished: 3 errors, 0 warnings (0 minutes, 1 seconds) ===|"

The problem is that you cannot run code in the global scope. The global scope is only for declarations or definitions, not for expressions (executing code). You have to move your setting for the Printed functor in the main function:

#include <iostream>
#include <string>
#include "events.h"

using namespace std;

class test
{
    public:
    events<> Printed{[]() { ; }};
    void write(string a)
    {
        cout << a;
        Printed();
    }

};


int main()
{
    test a;

    a.Printed = events<>{[]()
    {
        cout << "\nMessage printed\n";
    }};

    a.write("hello world");
    cin.get();
    return 0;
}

I think this should work, although I have no idea how "events" is set up.

//events.h
#ifndef events_H_INCLUDED
#define events_H_INCLUDED

#include <functional>
#include <vector>


template <class ... b>
class events
{
public:
    typedef std::function<void(b...argx )> OnSomethingHandler;

    events(OnSomethingHandler Handler)
    {
        handlers_=Handler;
    }

    void operator() (b&&... args)
    {
        handlers_ (std::forward<b> (args)...);
    }

    events& operator = (OnSomethingHandler Handler)
    {
        handlers_ = Handler;
        return *this;
    }

private:
    OnSomethingHandler handlers_;

};

#endif // events_H_INCLUDED

i'm sorry, if i'm overloading '()' operator, why i can't use it, outside of main?
(sorry, but my objective is do it ouside of the main)

I tested the code (that I posted in my last post, and using your implementation of the "events" class) and it all works, no warnings, no errors, and runs as expected, with the correct output.

if i'm overloading '()' operator, why i can't use it, outside of main?

It does not matter what you overload or not, you cannot execute code outside of any function's body. It's that simple. See this simple code:

// these lines are fine, 
//  they are 'definitions' of global variables. 
int a = 2;
int b = 3;

// this line is OK too, 
//  it's also a 'definition' of a global var.
int c = a + b;

// this line is an ERROR!
//  it's an 'expression' not a 'definition'
c = a * b;

At the global scope, you are allowed to declare stuff like classes, functions and variables, and you are allowed to define stuff like functions (by providing a body for the function) and variables (by providing an initial value / constructor-invocation). But, you are not allowed to write expressions that need to be evaluated. The compiler only issues "static initialization code" for the global objects, it cannot accomodate general expression evaluations (unless they are made a part of the construction of one of the global variables).

When you tried to give a new value to the data member a.Printed, that was an expression, just like the c = a * b; expression above, which is not allowed at the global / namespace scope. That was the error. It has nothing to do with the overloaded operators or anything like that, it's just a basic rule of C/C++.

commented: thanks +0

you even can use the '::' operator(well we can't overload it).
but i must give up on these thot :(
what you think about the Labdabeta code? he tell us that it's possible
thanks for all

I think Labdabeta misunderstood your code. He thought that your declaration of Printed was meant to be a function pointer to a function that takes no argument and returns a events<> object. In reality, your declaration of Printed was a declaration of a data member of type events<> with an in-declaration initializer (that uses the new {} uniform initialization syntax) to an empty lambda functor. Later, when he initializes the Printed function pointer to point to a lambda expression, it cannot work because the lambda expression must return an events<> object, instead of void. In other words, it doesn't work.

commented: thanks +2

ok..thanks for all

i'm sorry.. someone correct me 1 thing: i can change the static members at the global scope, right?

No, you cannot. You can have one definition of the static data member (i.e., constructor / initialization of the data member). But after that, you cannot modify the static member at the global scope, because that would have to be either an expression (which is not allowed), or a second definition (which would break the C++ One Definition Rule (ODR)). Of course, you can modify the static data member within any function, but not at global scope.

Here is a simple example:

class Foo {
  public:
    static int bar;  // <- 'declaration'
};

int Foo::bar = 42;  // <- 'definition'

Foo::bar = 69;  // ERROR: expressions not allowed at global scope.

int Foo::bar = 69;  // ERROR: re-definition of 'Foo::bar'

int main() {
  Foo::bar = 69;  // OK
};
int Foo::bar = 42; // <- 'definition'

you used the class name. can i use the instance\object name?

can i use the instance\object name?

Not for the definition. The member is a static data member, meaning that it is linked to the class, not an object. However, for expressions, you can access the static data member through the object, but this is just a syntax feature, the static member is still the same for all objects of the same class. Here is an extension to the example:

class Foo {
  public:
    static int bar;  // <- 'declaration'
};

int Foo::bar = 42;  // <- 'definition'

int main() {
  Foo f;
  f.bar = 69;  // OK
  std::cout << Foo::bar << std::endl; // <- this will print '69'
};
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.