472,975 Members | 1,320 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,975 software developers and data experts.

Problem with abstract base class

Suppose I have an abstract base class that looks like this:

template <typename T>
class base {
public: // Typedefs
typedef double value_type;
typedef std::size_t size_type;
public:
// Assignment operators.
virtual base<T>& operator=(const base<T>& rhs) = 0;
virtual base<T>& operator=(const value_type& rhs) = 0;
// Indexing operators.
virtual value_type& operator()(size_type i, size_type j) = 0;
virtual const value_type& operator()(size_type i, size_type j) const
= 0;
// Size functions.
virtual size_type size() const = 0;
virtual size_type rows() const = 0;
virtual size_type columns() const = 0;
// Elementwise mathematical operators
virtual base<T>& operator+=(const base<T>& rhs) = 0;
virtual base<T>& operator-=(const base<T>& rhs) = 0;
virtual base<T>& operator*=(const base<T>& rhs) = 0;
virtual base<T>& operator/=(const base<T>& rhs) = 0;
virtual base<T>& operator+=(const value_type& rhs) = 0;
virtual base<T>& operator-=(const value_type& rhs) = 0;
virtual base<T>& operator*=(const value_type& rhs) = 0;
virtual base<T>& operator/=(const value_type& rhs) = 0;
};

and a derived class:

template <typename T>
class image : public base<T> {
protected: // Data members
value_type *m_data;
size_type m_rows, m_columns;
public:
// Constructors and destructor.
image();
image(size_type m, size_type n);
image(size_type m, size_type n, const value_type& init);
image(const image<T>& rhs);
~image();
// Assignment operators.
image<T>& operator=(const base<T>& rhs);
image<T>& operator=(const value_type& rhs);
// Indexing operators.
value_type& operator()(size_type i, size_type j);
const value_type& operator()(size_type i, size_type j) const;
// Size functions.
size_type size() const;
size_type rows() const;
size_type columns() const;
// Elementwise mathematical operators
image<T>& operator+=(const base<T>& rhs);
image<T>& operator-=(const base<T>& rhs);
image<T>& operator*=(const base<T>& rhs);
image<T>& operator/=(const base<T>& rhs);
image<T>& operator+=(const value_type& rhs);
image<T>& operator-=(const value_type& rhs);
image<T>& operator*=(const value_type& rhs);
image<T>& operator/=(const value_type& rhs);
};

When i want to use the assignment operator in my code, even a simple
program won't compile:

int main(void)
{
image<double> im1(512,512), im2(512,512);
im1 = im2;
return 0;
}

With VC7.1 I receive this error message:

main.obj : error LNK2019: unresolved external symbol "public: virtual
class image::base<double> & __thiscall
image::base<double>::operator=(class image::base<double> const &)"
(??4?$base@N@image@@UAEAAV01@ABV01@@Z) referenced in function "public:
class image::image<double> & __thiscall
image::image<double>::operator=(class image::image<double> const &)"
(??4?$image@N@image@@QAEAAV01@ABV01@@Z)
Jul 23 '05 #1
7 1485
Jef Driesen wrote:
Suppose I have an abstract base class that looks like this:

template <typename T>
class base {
public:
// Assignment operators.
virtual base<T>& operator=(const base<T>& rhs) = 0; [...] };

and a derived class:

template <typename T>
class image : public base<T> {
public:
// Assignment operators.
image<T>& operator=(const base<T>& rhs); [...] };

When i want to use the assignment operator in my code, even a simple
program won't compile:
It won't *link*. It compiles apparently fine.

int main(void)
{
image<double> im1(512,512), im2(512,512);
im1 = im2;
return 0;
}

With VC7.1 I receive this error message:

main.obj : error LNK2019: unresolved external symbol "public: virtual
class image::base<double> & __thiscall
image::base<double>::operator=(class image::base<double> const &)"
(??4?$base@N@image@@UAEAAV01@ABV01@@Z) referenced in function "public:
class image::image<double> & __thiscall
image::image<double>::operator=(class image::image<double> const &)"
(??4?$image@N@image@@QAEAAV01@ABV01@@Z)


This is a FAQ. Search for "link error templates".

V
Jul 23 '05 #2
That's because you just declare the operator=(...), not define it.
Jul 23 '05 #3
Jef Driesen wrote:
YangWeiQin wrote:
That's because you just declare the operator=(...), not define it.

I only posted the declaration, but in my actual code the implementation
is provided. [...]


Provided WHERE?
Jul 23 '05 #4
On 2005-03-24, Jef Driesen <je********@hotmail.com.nospam> wrote:
I want to have multiple image-like classes (e.g. normal image,
subimage,...). And it should be possible to copy the pixels from one
image type to an image of another type. An example:

image im1(512,512), im2(256,256) // Create two images
range r(0,256);
subimage sub(im,r,r) // Create a subimage
im2 = sub; // Copy pixels from subimage


That's not an example of polymorphic assigment. You don't need
a virtual assignment operator to do that.

You should be able to implement it via the base class assignment operator
along these lines:

base& operator=(const base& x) {
image tmp(x.width(),x.height()); // make it exception safe
for (int i = 0; i < width(); ++i)
for (int j = 0; j < height(); ++j )
tmp.setPixel(i,j,x.getPixel(i,j));
swap(tmp);
}

You want to make sure you're not slicing though. Places where you think you
"need" a virtual assignment operator are also places where you're likely to
slice.

Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
Jul 23 '05 #5
On 2005-03-24, Donovan Rebbechi <ab***@aol.com> wrote:
That's not an example of polymorphic assigment. You don't need
a virtual assignment operator to do that.

You should be able to implement it via the base class assignment operator
along these lines:

base& operator=(const base& x) {
image tmp(x.width(),x.height()); // make it exception safe
for (int i = 0; i < width(); ++i)
for (int j = 0; j < height(); ++j )
tmp.setPixel(i,j,x.getPixel(i,j));
swap(tmp);
}


Actually, I think I'm starting to see what the problem is (one of them anyway).
If your subimage class references but doesn't own memory, then you can't
allocate new memory for it. But with a subimage, you can't even "assign" to it
in this sense, unless you're assigning an image that has the same dimensions as
the subimage.

So that raises the question -- does your "polymorphic assignment" resize and
copy, or does it require the precondition
width()==rhs.width && height()==rhs.height())
? It's a bad idea to have a polymorphic function do two substantially
different things for different types. For example, what does this do ?
void foo (base& lhs, base& rhs ) { lhs = rhs; }

My suggestion would be to use assignment in the usual idiomatic C++ way:
primarily as a copy-assign, secondarily as a conversion function.

Write a separate function to handle *element-wise* assignment, and make that
function require that image dimensions match.

Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
Jul 23 '05 #6
Victor Bazarov wrote:
Jef Driesen wrote:
YangWeiQin wrote:
That's because you just declare the operator=(...), not define it.


I only posted the declaration, but in my actual code the
implementation is provided. [...]

Provided WHERE?


In the header file.
Jul 23 '05 #7
Jef Driesen wrote:
Victor Bazarov wrote:
Jef Driesen wrote:
YangWeiQin wrote:

That's because you just declare the operator=(...), not define it.


I only posted the declaration, but in my actual code the
implementation is provided. [...]


Provided WHERE?

In the header file.


OK. Just making sure.
Jul 23 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Nico Massi | last post by:
i have a problem with my classes i have a base class that defines the interface for a window ( abstract class ) in a render device i have implemented the class for either Direct3D or OpenGL on...
3
by: Omer van Kloeten | last post by:
The Top Level Design: The class Base is a factory class with a twist. It uses the Assembly/Type classes to extract all types that inherit from it and add them to the list of types that inherit...
15
by: Tee | last post by:
Hi, I have a base usercontrol with a method (blank method, no code), I have another few usercontrols that will inherit this base usercontrol, but I want to force all the usercontrol that...
2
by: Dave Veeneman | last post by:
Is is legal to declare abstract members in non-abstract classes? How about non-abstract members in abstract classes? I am writing a base class with three derived classes. The base class will...
6
by: Dan Sikorsky | last post by:
If we were to define all abstract methods in an abstract class, thereby making that class non-abstract, and then override the heretofore 'abstract' methods in a derived class, wouldn't that remove...
9
by: Sean Kirkpatrick | last post by:
To my eye, there doesn't seem to be a whole lot of difference between the two of them from a functional point of view. Can someone give me a good explanation of why one vs the other? Sean
9
by: silversurfer2025 | last post by:
Hello everyone, I am currently having problems with a C++ abstract class. I have a class FrameWork.h which defines some methods (of which some are abstract, i.e. virtual void method() = 0). In...
7
by: jason | last post by:
In the microsoft starter kit Time Tracker application, the data access layer code consist of three cs files. DataAccessHelper.cs DataAcess.cs SQLDataAccessLayer.cs DataAcccessHelper appears...
0
by: emin.shopper | last post by:
I had a need recently to check if my subclasses properly implemented the desired interface and wished that I could use something like an abstract base class in python. After reading up on metaclass...
4
by: David Zha0 | last post by:
Hi, "when we call a virtual method, the runtime will check the instance who called the method and then choose the suitable override method, this may causes the performance drop down", is this...
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.