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) 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
That's because you just declare the operator=(...), not define it.
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?
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/
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/
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.
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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...
|
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...
|
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...
|
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
|
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...
|
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...
|
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...
|
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...
|
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
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
|
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,...
|
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...
|
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,...
|
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...
| |