Nusrat Nuriyev
asked on
multiple definition of method
class Shape
{
public:
BLOCK blocks[4];
SHAPE_TYPE whoami;
friend Table;
Table *tbl;
// Default constructor
Shape() {};
//Shape(Table *tbl) { this->tbl = tbl;}
public:
// non-virtual
void DrawSingleBlock(BLOCK block)
{
RECT rect;
HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
rect.top = (*tbl).initial_point.y + block.Y * (*tbl).cell.height;
rect.left = (*tbl).initial_point.x + block.X * (*tbl).cell.width;
rect.bottom = rect.top + tbl->cell.height;
rect.right = rect.left + tbl->cell.width;
FillRect(tbl->hdc, &rect, brush);
}
// virtual
virtual void Draw(void) {};
virtual void Rotate(ROTATE_DIR rdir){ return; };
virtual bool isRotatable(ROTATE_DIR rdir){ return false;};
};
class LineShape : public Shape
{
public:
LineShape();
LineShape(Table *tbl, BLOCK start_block)
{
this->tbl = tbl;
for (int i = 0; i < 4; i++)
{
this->blocks[i].X = start_block.X;
this->blocks[i].Y = start_block.Y + i;
}
}
public:
bool isRotatable(ROTATE_DIR rdir) { return false; };
void Rotate(ROTATE_DIR rdir) { return; };
void Draw(void); // { }
};
/*
LineShape::LineShape(Table *tbl, BLOCK start_block) : Shape(tbl)
{
}
*/
void LineShape::Draw(void)
{
for (int i = 0; i < 4; i++)
{
DrawSingleBlock(blocks[i]);
}
}
||=== Build: Debug in Tetris (compiler: GNU GCC Compiler) ===|
obj\Debug\Table.o||In function `ZN9LineShape4DrawEv':|
C:\codeblocks\Tetris\Table
obj\Debug\main.o:C:\codebl
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|
Where is that "multiple" definition?
ASKER
nope
this does not work.
class Shape
{
public:
BLOCK blocks[4];
SHAPE_TYPE whoami;
friend Table;
Table *tbl;
// Default constructor
Shape() {};
//Shape(Table *tbl) { this->tbl = tbl;}
public:
// non-virtual
void DrawSingleBlock(BLOCK block)
{
RECT rect;
HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
rect.top = (*tbl).initial_point.y + block.Y * (*tbl).cell.height;
rect.left = (*tbl).initial_point.x + block.X * (*tbl).cell.width;
rect.bottom = rect.top + tbl->cell.height;
rect.right = rect.left + tbl->cell.width;
FillRect(tbl->hdc, &rect, brush);
}
// virtual
virtual void Draw(void) {};
virtual void Rotate(ROTATE_DIR rdir){ return; };
virtual bool isRotatable(ROTATE_DIR rdir){ return false;};
};
class LineShape : public Shape
{
public:
LineShape();
LineShape(Table *tbl, BLOCK start_block)
{
this->tbl = tbl;
for (int i = 0; i < 4; i++)
{
this->blocks[i].X = start_block.X;
this->blocks[i].Y = start_block.Y + i;
}
}
public:
bool isRotatable(ROTATE_DIR rdir) { return false; };
void Rotate(ROTATE_DIR rdir) { return; };
virtual void Draw(void); // { }
};
/*
LineShape::LineShape(Table *tbl, BLOCK start_block) : Shape(tbl)
{
}
*/
void LineShape::Draw(void)
{
for (int i = 0; i < 4; i++)
{
DrawSingleBlock(blocks[i]);
}
}
this does not work.
ASKER
However,
this does work.
Again, what is the problem?
class Shape
{
public:
BLOCK blocks[4];
SHAPE_TYPE whoami;
friend Table;
Table *tbl;
// Default constructor
Shape() {};
//Shape(Table *tbl) { this->tbl = tbl;}
public:
// non-virtual
void DrawSingleBlock(BLOCK block)
{
RECT rect;
HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
rect.top = (*tbl).initial_point.y + block.Y * (*tbl).cell.height;
rect.left = (*tbl).initial_point.x + block.X * (*tbl).cell.width;
rect.bottom = rect.top + tbl->cell.height;
rect.right = rect.left + tbl->cell.width;
FillRect(tbl->hdc, &rect, brush);
}
// virtual
virtual void Draw(void) {};
virtual void Rotate(ROTATE_DIR rdir){ return; };
virtual bool isRotatable(ROTATE_DIR rdir){ return false;};
};
class LineShape : public Shape
{
public:
LineShape();
LineShape(Table *tbl, BLOCK start_block)
{
this->tbl = tbl;
for (int i = 0; i < 4; i++)
{
this->blocks[i].X = start_block.X;
this->blocks[i].Y = start_block.Y + i;
}
}
public:
bool isRotatable(ROTATE_DIR rdir) { return false; };
void Rotate(ROTATE_DIR rdir) { return; };
virtual void Draw(void) { for (int i = 0; i < 4; i++)
{
DrawSingleBlock(blocks[i]);
} }
};
this does work.
Again, what is the problem?
It works for me.
The following code was compiled using Microsoft Visual Stdio 2010. I created a new project. I added a file "Shape.cpp" to the project, and inserted the following code (note the dummy classes I had to create to account for the "missing" source code your sample didn't include).
Logically, your latest two samples are the same. The only difference is the 2nd didn't define the Draw() function 'in-line'. But that shouldn't matter.
The following code was compiled using Microsoft Visual Stdio 2010. I created a new project. I added a file "Shape.cpp" to the project, and inserted the following code (note the dummy classes I had to create to account for the "missing" source code your sample didn't include).
#include "stdafx.h"
class BLOCK
{
public:
int X;
int Y;
};
class Cell
{
public:
int height;
int width;
};
#define SHAPE_TYPE int
#define ROTATE_DIR int
class Table
{
public:
Table(){};
POINT initial_point;
Cell cell;
HDC hdc;
};
class Shape
{
public:
BLOCK blocks[4];
SHAPE_TYPE whoami;
friend Table;
Table *tbl;
// Default constructor
Shape() {};
//Shape(Table *tbl) { this->tbl = tbl;}
public:
// non-virtual
void DrawSingleBlock(BLOCK block)
{
RECT rect;
HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
rect.top = (*tbl).initial_point.y + block.Y * (*tbl).cell.height;
rect.left = (*tbl).initial_point.x + block.X * (*tbl).cell.width;
rect.bottom = rect.top + tbl->cell.height;
rect.right = rect.left + tbl->cell.width;
FillRect(tbl->hdc, &rect, brush);
}
// virtual
virtual void Draw(void) {};
virtual void Rotate(ROTATE_DIR rdir){ return; };
virtual bool isRotatable(ROTATE_DIR rdir){ return false;};
};
class LineShape : public Shape
{
public:
LineShape();
LineShape(Table *tbl, BLOCK start_block)
{
this->tbl = tbl;
for (int i = 0; i < 4; i++)
{
this->blocks[i].X = start_block.X;
this->blocks[i].Y = start_block.Y + i;
}
}
public:
bool isRotatable(ROTATE_DIR rdir) { return false; };
void Rotate(ROTATE_DIR rdir) { return; };
virtual void Draw(void); // { }
};
/*
LineShape::LineShape(Table *tbl, BLOCK start_block) : Shape(tbl)
{
}
*/
void LineShape::Draw(void)
{
for (int i = 0; i < 4; i++)
{
DrawSingleBlock(blocks[i]);
}
}
Logically, your latest two samples are the same. The only difference is the 2nd didn't define the Draw() function 'in-line'. But that shouldn't matter.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
or.
(5) declare the function as inline in header file but not in the class.
I have used (1).
About (5).
Are the all function inline in template class?
(5) declare the function as inline in header file but not in the class.
I have used (1).
About (5).
Are the all function inline in template class?
no, the functions are not really 'inline' but the compilation of the function happens in the calling function when a concrete template type was known and the template was instantiated with that type.
for example if you have class MyContainer<T> with member function 'void insert(const T & t)', the MyContainer<short::insert( const short & t) was compiled if you do like
but, different to an inline function, the compiler doesn't embed the code into the calling function but adds a new function and a call. if the same function was called again, it uses the same function module (while an inline function would be embedded again)
Sara
for example if you have class MyContainer<T> with member function 'void insert(const T & t)', the MyContainer<short::insert(
...
MyContainer<short> mys; // here the class was instantiated
mys.insert(-1); // here the insert function was compiled (if 1st call)
but, different to an inline function, the compiler doesn't embed the code into the calling function but adds a new function and a call. if the same function was called again, it uses the same function module (while an inline function would be embedded again)
(5) declare the function as inline in header file but not in the class.where do you see a difference to (3) ?
Sara
ASKER
Thanks,
where do you see a difference to (3) ?Nowhere, it was an illusion.
The child class 'LineShape' has a Draw function this is not declared as virtual.
Since LineShape inherited the virtual Draw of Shape, you have two different definitions of Draw in LineShape.
Simply add the virtual key word to your Draw function in LineShape. That way, the Draw function in LineShape will "over-ride" the Draw function it inherited from Shape.