Can you help? Problem about virtual function


#include <stdio.h>
#include <vector>

struct TPoint
{
TPoint (double ax,double ay,double az) {x=ax; y=ay;z=az;};
double x,y,z;

};

struct TTwoPoint
{
TPoint *SP;
TPoint *EP;

TTwoPoint(double x1,double y1,double z1,double x2,double y2,double z2)
{
SP = new TPoint(x1,y1,z1);
EP = new TPoint(x2,y2,z2);
};

TTwoPoint(TPoint S,TPoint E) {SP=&S;EP=&E;};
};



class TObject
{
private:

protected:
public:
virtual void Draw() = 0 ;
TObject() {};
~TObject() {};

};

class TLine : public TObject
{
private:
TTwoPoint *Loc;
protected:
public:
TLine(TPoint *StP,TPoint *EndP) {Loc->SP = StP;Loc->EP=EndP ;};
static void Draw();

};

class TObjGroup : public TObject
{
private:
std::vector<TObject*> Objects;
protected:
public:
TObjGroup(TObject *Obj) {};
~TObjGroup() {};
void Draw();
void AddObject(TObject *AnObj);
};

void TObjGroup::Draw()
{
for (unsigned i=0; i< Objects.size();i++)
{
Objects[i]->Draw();
};
};

void TObjGroup::AddObject(TObject *AnObj)
{
Objects.push_back(AnObj);
};


int main( int argc, const char* argv[] )
{
TObjGroup *Objs = new TObjGroup(new TLine(new TPoint(0,0,0),new TPoint(100,100,0)));

return 0;

};


it gives error about abstract method???
1. You can't have a virtual static function.
2. You don't have a definition for TLine::Draw()
Last edited on
Even after removing the static declaration and defining TLine::Draw() the program crashes and the debugger pinpoints the problem at TLine(TPoint *StP,TPoint *EndP) {Loc->SP = StP;Loc->EP=EndP ;};
Here you need to use the already defined TTwoPoint ctor: Loc = new TTwoPoint(StP, EndP); as piecewise assignment in your code to Loc->SP, Loc->EP is not actually creating the TTwoPoint object that Loc is going to point to
Then the following statement makes no sense:
 
TObjGroup *Objs = new TObjGroup(new TLine(new TPoint(0,0,0),new TPoint(100,100,0)));

You can create a new TLine from the given TPoint objects (0,0,0), (100,100,0) in the following way:
1
2
TLine line(new TPoint(0,0,0), new TPoint(100,100,0));
TObject* Obj = &line;//assign address of line to TObject* 

but there is nothing in the TObjGroup ctor that links a TLine object to the TObjGroup class.
In fact class TObjGroup seems ill-formed as its data-member is a std::vector<TObjects*> while the ctor takes an argument of type TObject* - how do you propose to link the two? Think carefully about what you're trying to achieve before rushing into further code. Here's the complete program as it stands now:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>//C++ header file
#include <vector>
//USE INDENTATIONS AND SPACING TRHOUGHOUT!!!
struct TPoint
{
    TPoint (const double& ax, const double& ay, const double& az)//const qualify, pass by ref
        : x(ax), y(ay), z(az) {}

    double x;     double y;     double z;
};
struct TTwoPoint
{
    const TPoint* SP;//be consistent, either declare data members first or methods first
    const TPoint* EP;

    TTwoPoint(const double& x1, const double& y1, const double& z1,
              const double& x2, const double& y2, const double& z2)
    :SP (new TPoint(x1,y1,z1)), EP (new TPoint(x2,y2,z2)) {}

    TTwoPoint(const TPoint* S, const TPoint* E)
    :SP(S), EP(E) {}
};
class TObject
{
    public:
        virtual void Draw() = 0 ;
        TObject() {}
        ~TObject() {}
};
class TLine : public TObject
{
    private:
        TTwoPoint* Loc;
    public:
        TLine(const TPoint* StP, const TPoint* EndP)
        {
          //  Loc -> SP = StP;
          //  Loc -> EP = EndP;
          Loc = new TTwoPoint(StP, EndP);
        }
        void Draw() {}
};
class TObjGroup : public TObject
{
    private:
        std::vector<TObject*> Objects;

    public:
        TObjGroup(TObject* Obj) {}
        ~TObjGroup() {}
        void Draw();
        void AddObject(TObject* AnObj);
};
void TObjGroup::Draw()
{
    for (unsigned i=0; i< Objects.size();i++)
    {
        Objects[i]->Draw();
    };
};
void TObjGroup::AddObject(TObject *AnObj)
{
    Objects.push_back(AnObj);
};
int main( int argc, const char* argv[] )
{
//TObjGroup *Objs = TObjGroup(TLine(new TPoint(0,0,0),new TPoint(100,100,0)));
TLine line(new TPoint(0,0,0), new TPoint(100,100,0));
TObject* Obj = &line;
};


Finally, following link explains why virtual and static don't mix:
http://stackoverflow.com/questions/9863007/can-we-have-a-static-virtual-functions-if-not-then-why
Last edited on
Thanks for your kind answer , I changed the things but you are rigt about the declaration of std::vector<TObjects*> is a problem for me now the compiler gives me error error LNK2001: unresolved external symbol "private: static class std::vector<class TObject,class std::allocator<class TObject> > TObjGroup::Objects" (?Objects@TObjGroup@@0V?$vector@VTObject@@V?$allocator@VTObject@@@std@@@std@@A) , and linking about TLine to TObject I will send a variable type of TObject and construct it with the TLine constructor so i want to use polymorphism and dynamic type ... your opinian and solve about Objects?
and linking about TLine to TObject I will send a variable type of TObject and construct it with the TLine constructor

It is perfectly legitimate for abstract base classes to have ctor's though these classes can't be instantiated:
http://stackoverflow.com/questions/19808667/c-abstract-class-constructor-yes-or-no
So think of how you can pass a TLine object to the TObject ctor and you can call that ctor from class TObjGroup (since the latter is derived from TObject)
Also the fact that TObjGroup is derived from TObject means that you can assign to TObject* and don't necessarily need TObjGroup* - this addresses polymorphism and, potentially with appropriate dynamic_cast to TObjGroup, run-time type identification (RTTI) though since TObject can't be instantiated I'm not sure if this would provide any meaningful information as the cast should always be valid unless there are further levels of inheritance
Another thing to note is that you don't have any pointers to the heap objects new TPoint(0,0,0), new TPoint(100,100,0) so I'm not sure how you'd delete them. You could either (a) use smart pointers or (b) declare pointers to them and delete these pointers when the objects in question are no longer required
Finally, both TTwoPoint and TLine ctor's acquire resources through the new operator so here too consider (a) use of smart pointers or (b) explicitly defined destructor which would then take you into the realm of the Rule of Three/Five:
http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three

Another link to the rule of 3/5/0 :

http://en.cppreference.com/w/cpp/language/rule_of_three
Topic archived. No new replies allowed.