473,405 Members | 2,310 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,405 software developers and data experts.

deriving and 'overloading' of an attribute

63
What I want to do is something like this:

Expand|Select|Wrap|Line Numbers
  1. class A{
  2.   protected:
  3.     vector<int> data;
  4.   public:
  5.     doit(){
  6.       // work on the onedimensional data
  7.     }
  8. }
  9.  
  10. class B : class A {
  11.   protected:
  12.     vector<vector<int>> data; // overload the data
  13.   public:
  14.     doit(){
  15.       // work on the twodimensional data
  16.     }
  17. }
  18.  
So in B one of the members (data) of A is replaced and those methods that work on data have to be changed, but A and B still do have a lot in common (unlike from what my minimal example shows)

I have started to implement it this way and it does work, but I feel that this is no good design, since both versions of the attribute data do exist in an instance of B. I would rather want to somehow really replace the onedimensional version. I was thinking of maybe adding an assertion in B to ensure that the A::data is not initilized, but thats only an ugly hack and no solution. I guess that this is not such an infrequent problem, only I could not find any useful answers myself.

I hope my question is understandable and I'd be glad if someone could point me in the right direction.
Jan 23 '08 #1
8 1913
Ganon11
3,652 Expert 2GB
I don't think it's possible to overload a data member - in other words, your current implementation (having both B::data and A::data present in B) may be your only implementation possible. You could make A::data private so that B is unaware of its existence, but I think it will still exist.
Jan 23 '08 #2
weaknessforcats
9,208 Expert Mod 8TB
Do keep in mind that a vector<int> can have any dimensions you need.

For example, if there are 12 ints in the vector, you could say that it is an array of [12] or an array [6][2] or an array [4][3] or an array [2][2][3]. You manage the dimensions by using iterators.

You just need the one vector<int> in the base class. The iterators for the dimensions can be in the derived classes.
Jan 24 '08 #3
jabbah
63
thanks ganon11 and weaknessforcats and sorry for answering so late - was away from work.


a friend has suggested that I could make another class C which has the common things and then A and B each derive directly from C. ( Now that I wrote it down it sounds so easy that I guess that was what I was looking for. )


still I'm puzzling with this:
Do keep in mind that a vector<int> can have any dimensions you need.

For example, if there are 12 ints in the vector, you could say that it is an array of [12] or an array [6][2] or an array [4][3] or an array [2][2][3]. You manage the dimensions by using iterators.

You just need the one vector<int> in the base class. The iterators for the dimensions can be in the derived classes.
That sounds as if you would suggest that I could remove line 12 of the code above and somehow manage to write data[i][j] inside of B::doit(). That can't possibly work, can it? I dont get what you mean.
Jan 30 '08 #4
weaknessforcats
9,208 Expert Mod 8TB
I dont get what you mean.
Assume the vector<int> is in the base class.

Let's assume I want to use it as a 2D int array of [4][3].

I derive a class MyClass from class A. Inside MyClass are row and col variables

Suppose I want row 2 col 1.

Row 2 is 3 * 2 or 6.

Col 1 is 1.

So element [2][1] is 6 + 1 or element [7] in the vector.

It's the same calculation the compiler makes to get the element [2][1] when you use the address of element 0 as the starting point.

Read this:
First, there are only one-dimensional arrays in C or C++. The number of elements in put between brackets:
Expand|Select|Wrap|Line Numbers
  1. int array[5];
  2.  
That is an array of 5 elements each of which is an int.

Expand|Select|Wrap|Line Numbers
  1. int array[];
  2.  
won't compile. You need to declare the number of elements.

Second, this array:
Expand|Select|Wrap|Line Numbers
  1. int array[5][10];
  2.  
is still an array of 5 elements. Each element is an array of 10 int.

Expand|Select|Wrap|Line Numbers
  1. int array[5][10][15];
  2.  
is still an array of 5 elements. Each element is an array of 10 elements where each element is an array of 15 int.


Expand|Select|Wrap|Line Numbers
  1. int array[][10];
  2.  
won't compile. You need to declare the number of elements.

Third, the name of an array is the address of element 0
Expand|Select|Wrap|Line Numbers
  1. int array[5];
  2.  
Here array is the address of array[0]. Since array[0] is an int, array is the address of an int. You can assign the name array to an int*.

Expand|Select|Wrap|Line Numbers
  1. int array[5][10];
  2.  
Here array is the address of array[0]. Since array[0] is an array of 10 int, array is the address of an array of 10 int. You can assign the name array to a pointer to an array of 10 int:
Expand|Select|Wrap|Line Numbers
  1. int array[5][10];
  2.  
  3. int (*ptr)[10] = array;
  4.  
Fourth, when the number of elements is not known at compile time, you create the array dynamically:

Expand|Select|Wrap|Line Numbers
  1. int* array = new int[value];
  2. int (*ptr)[10] = new int[value][10];
  3. int (*ptr)[10][15] = new int[value][10][15];
  4.  
In each case value is the number of elements. Any other brackets only describe the elements.

Using an int** for an array of arrays is incorrect and produces wrong answers using pointer arithmetic. The compiler knows this so it won't compile this code:

Expand|Select|Wrap|Line Numbers
  1. int** ptr = new int[value][10];    //ERROR
  2.  
new returns the address of an array of 10 int and that isn't the same as an int**.

Likewise:
Expand|Select|Wrap|Line Numbers
  1. int*** ptr = new int[value][10][15];    //ERROR
  2.  
new returns the address of an array of 10 elements where each element is an array of 15 int and that isn't the same as an int***.

With the above in mind this array:
Expand|Select|Wrap|Line Numbers
  1. int array[10] = {0,1,2,3,4,5,6,7,8,9};
  2.  
has a memory layout of

0 1 2 3 4 5 6 7 8 9

Wheras this array:
Expand|Select|Wrap|Line Numbers
  1. int array[5][2] = {0,1,2,3,4,5,6,7,8,9};
  2.  
has a memory layout of

0 1 2 3 4 5 6 7 8 9

Kinda the same, right?

So if your disc file contains

0 1 2 3 4 5 6 7 8 9

Does it make a difference wheher you read into a one-dimensional array or a two-dimensional array? No.

Therefore, when you do your read use the address of array[0][0] and read as though you have a
one-dimensional array and the values will be in the correct locations.
Jan 31 '08 #5
jabbah
63
ok, got it. thanks weaknessforcats.
Feb 4 '08 #6
bfoo75
12
you could always make an abstract base class:
Expand|Select|Wrap|Line Numbers
  1.  
  2. class base {
  3.   public:
  4.     virtual void doit() = 0
  5. }
  6.  
  7. class A : class base {
  8.   protected:
  9.     vector<int> data;
  10.   public:
  11.     doit(){
  12.       // work on the onedimensional data
  13.     }
  14. }
  15.  
  16. class B : class base {
  17.   protected:
  18.     vector<vector<int>> data; // overload the data
  19.   public:
  20.     doit(){
  21.       // work on the twodimensional data
  22.     }
  23. }
  24.  
  25.  
Feb 4 '08 #7
weaknessforcats
9,208 Expert Mod 8TB
class base {
public:
virtual void doit() = 0
}

class A : class base {
protected:
vector<int> data;
public:
doit(){
// work on the onedimensional data
}
}

class B : class base {
protected:
vector<vector<int>> data; // overload the data
public:
doit(){
// work on the twodimensional data
}
}
The whole point is to not overload the data.
Feb 5 '08 #8
jabbah
63
you could always make an abstract base class
Yeah and I think thats just plainly the right thing (tm) to do in this situation and I was just caught somewhere in my thinking and couldnt find the base class (not necessarily abstract) in my head.


The whole point is to not overload the data.
Right, I felt uncomfortable with my first attempt and I was just wondering whether there was something wrong with my approach of overloading data, or whether thats something one should avoid at all.


Regarding your suggestion:
if there are 12 ints in the vector, you could say that it is an array of [12] or an array [6][2] or an array [4][3] or an array [2][2][3].
Im not going to do this in my current situation, but I'll try to keep it somewhere in my brain. - its an interesting idea.

thanks anybody
Feb 6 '08 #9

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: Sergey Krushinsky | last post by:
Hello all, Is there a common way to emulate constructor overloading in Python class? For instanse, I have 3 classes: 1/ Polar - to hold polar coordinates; 2/ Cartesian - to hold cartesian...
7
by: Doran_Dermot | last post by:
Hi All, I've seen lots of code in which the attributes of a class are accessed and modified using two separate methods. For example: class Problems: def __init__( self, refNum ):...
8
by: Sebastien Boisgerault | last post by:
I wonder if the following quotation from the Python Reference Manual (release 2.3.3) about operator overloading is true : "For example, if a class defines a method named __getitem__(), and x is...
28
by: Steven T. Hatton | last post by:
This may be another question having an obvious answer, but I'm not seeing it. I'm trying to create a class that derives from std::valarray<std::string>. I don't need a template, and I haven't come...
2
by: Julian | last post by:
I would like to have output from my program to be written to cout as well as a file. (actually, i want several other output options but this should explain my problem in the simplest way). I have...
4
by: John Smith | last post by:
can we overload a javascript function with different argument? example: function a(a){} function a(a,b){}
0
by: Marcin Grzębski | last post by:
Hi Group, I know that if i want to run a windows form with ActiveX control and variables on it, i have to set attribute for Main() function. But if i want to deriving this form in other form...
13
by: Jon Cosby | last post by:
VB .Net does support operator overloading, doesn't it? It seems like this should overload binary addition, but VB doesn't recognize "Operator" Public Shared Operator +(ByVal c1 as cnum, ByVal c2...
5
by: Mr.SpOOn | last post by:
Hi, in a project I'm overloading a lot of comparison and arithmetic operators to make them working with more complex classes that I defined. Sometimes I need a different behavior of the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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.