473,399 Members | 2,774 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 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 1507
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...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.