473,395 Members | 1,706 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,395 software developers and data experts.

Making a constructor 'const'.

SzH

Is it possible for a constructor to know if the object has been
initialised as a 'const' ot not? The example at at end of the message
illustrates what I would like to do.

I want to allow constructing a 'const Aref' from a 'const A' [1], so I
added another constructor to 'Aref'. But I don't want to allow creating
a non-const Aref from a 'const A' [2] to prevent accidental modification
of a const A by Aref::set().

I tried to make the second constructor 'const', but found that this is
impossible.
class A {
int data;
public:
A(int i) : data(i) { }

int read() const { return data; }
void set(int val) { data = val; }
};

class Aref {
A &ref;
public:
Aref(A &a) : ref(a) { }

// added this constructor to allow [1]:
Aref(const A &a) : ref(const_cast<A&>(a)) { }
// but it is not possible to declare a constructor const
// to disallow [2]!

int read() const { return ref.read(); }
void set(int val) { ref.set(val); }
};

int main() {
const A a = 1;
const Aref ar1 = a; // should be allowed [1]
Aref ar2 = a; // should be illegal [2]
}
Apr 25 '07 #1
9 6481
* SzH:
>
class A {
int data;
public:
A(int i) : data(i) { }

int read() const { return data; }
void set(int val) { data = val; }
};

class Aref {
A &ref;
public:
Aref(A &a) : ref(a) { }

// added this constructor to allow [1]:
Aref(const A &a) : ref(const_cast<A&>(a)) { }
// but it is not possible to declare a constructor const
// to disallow [2]!

int read() const { return ref.read(); }
void set(int val) { ref.set(val); }
};

int main() {
const A a = 1;
const Aref ar1 = a; // should be allowed [1]
Aref ar2 = a; // should be illegal [2]
}
Use two classes ARef and ARefConst.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Apr 25 '07 #2
* SzH:
>
Is it possible for a constructor to know if the object has been
initialised as a 'const' ot not?
Not unless you tell it.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Apr 25 '07 #3
SzH
Alf P. Steinbach wrote:
>
Use two classes ARef and ARefConst.
This is what I would like to avoid (otherwise all const members of Aref
should be duplicated in ArefConst). It must also be possible to replace
an ArefConst by an Aref, but using inheritance/virtual functions is not
an option because of performance reasons.

Actually in my program A is an array of numerical values, but in some
circumstances it is preferable to treat certain ranges of an array
separately. For this purpose I made a slice (Aref) class that references
an array and simply allows to index a range of elements in it, e.g. it
is possible to "name" elements 10..20 of an array and index them from 0..10.

There were no problems until I tried to make slices writeable.

Any suggestions for implementing this?
Apr 25 '07 #4
SzH
Alf P. Steinbach wrote:
* SzH:
>>
Is it possible for a constructor to know if the object has been
initialised as a 'const' ot not?

Not unless you tell it.
Why does C++ forbid making constructors const? Is this going to be
included in the next version of the standard?

I found this (dates 1995):
http://www.open-std.org/jtc1/sc22/wg...1995/N0798.htm
Why was the proposal rejected?
Apr 25 '07 #5
* SzH:
Alf P. Steinbach wrote:
>>
Use two classes ARef and ARefConst.

This is what I would like to avoid (otherwise all const members of Aref
should be duplicated in ArefConst). It must also be possible to replace
an ArefConst by an Aref,
Inheritance or conversion.

but using inheritance/virtual functions is not
an option because of performance reasons.
Measure.

Actually in my program A is an array of numerical values, but in some
circumstances it is preferable to treat certain ranges of an array
separately. For this purpose I made a slice (Aref) class that references
an array and simply allows to index a range of elements in it, e.g. it
is possible to "name" elements 10..20 of an array and index them from
0..10.

There were no problems until I tried to make slices writeable.

Any suggestions for implementing this?
Have you looked at std::valarray?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Apr 25 '07 #6
SzH a écrit :
Alf P. Steinbach wrote:
>>
Use two classes ARef and ARefConst.

This is what I would like to avoid (otherwise all const members of Aref
should be duplicated in ArefConst). It must also be possible to replace
an ArefConst by an Aref, but using inheritance/virtual functions is not
an option because of performance reasons.
Then use template.
Actually in my program A is an array of numerical values, but in some
circumstances it is preferable to treat certain ranges of an array
separately. For this purpose I made a slice (Aref) class that references
an array and simply allows to index a range of elements in it, e.g. it
is possible to "name" elements 10..20 of an array and index them from
0..10.

There were no problems until I tried to make slices writeable.

Any suggestions for implementing this?
The STL chose to create the const_iterator trait.
IMO Alf P. Steinbach's suggestion is the one you need.

Now if you want settle for a runtime solution you can use a boolean to
know if you can modify the reference or not.

class Aref {
A &ref;
bool is_const;

public:
Aref(A &a) : ref(a),is_const(false) { }
explicit Aref(const A &a) : ref(const_cast<A&>(a)),is_const(true) {}

int read() const { return ref.read(); }
void set(int val)
{
if(this->is_const)
throw std::runtime_error("access violation");
ref.set(val);
}
};

Then
A a1(1);
Aref ar1(a1);
ar1.set(0);//OK

const A a2(2);
Aref ar2(a2);
ar2.set(0);//Throw

Michael
Apr 25 '07 #7
SzH a écrit :
Alf P. Steinbach wrote:
>* SzH:
>>>
Is it possible for a constructor to know if the object has been
initialised as a 'const' ot not?

Not unless you tell it.

Why does C++ forbid making constructors const? Is this going to be
included in the next version of the standard?

I found this (dates 1995):
http://www.open-std.org/jtc1/sc22/wg...1995/N0798.htm
Why was the proposal rejected?
What is basically proposed is to restrict the kind of cv-instanciation
depending on the cv of the parameter. This means (in the case of the
wrapper class) that the storage into the class in not const thus forcing
a cons_cast of the parameter in the const case; relying on the constness
of the wrapper class.

But, doing so, you have no constness check wihtin the wrapper class.
a method:
// taking the example of the OP
void set(int val)const
{
this->ref.set(val); //this is legal although parameter is const
}

This can lead to nasty bug.

The solution would be to have a keyword specifying the member inherits
its constness from the constness of the class (the inverse of mutable)
and have:

class Aref{
elbatum A& ref;

public:
Aref(A& a):ref(a){}//ref is not const
const Aref(A&):ref(a){}//ref is const
private:
Aref(const A& a);
//....
};

Michael
Apr 25 '07 #8
Michael DOUBEZ a écrit :
SzH a écrit :
>Alf P. Steinbach wrote:
>>* SzH:

Is it possible for a constructor to know if the object has been
initialised as a 'const' ot not?

Not unless you tell it.

Why does C++ forbid making constructors const? Is this going to be
included in the next version of the standard?

I found this (dates 1995):
http://www.open-std.org/jtc1/sc22/wg...1995/N0798.htm
Why was the proposal rejected?

What is basically proposed is to restrict the kind of cv-instanciation
depending on the cv of the parameter. This means (in the case of the
wrapper class) that the storage into the class in not const thus forcing
a cons_cast of the parameter in the const case; relying on the constness
of the wrapper class.

But, doing so, you have no constness check wihtin the wrapper class.
a method:
// taking the example of the OP
void set(int val)const
{
this->ref.set(val); //this is legal although parameter is const
Oups! This is not legal of course with a reference.
Let's make it a pointer
this->ref->set(val);

Michael
Apr 25 '07 #9
Michael DOUBEZ a écrit :
> this->ref.set(val); //this is legal although parameter is const

Oups! This is not legal of course with a reference.
Let's make it a pointer
this->ref->set(val);
Gosh! It is legal.
this->ref.set(val); //this is legal although parameter is const

Sorry for polluting the group.

Michael
Apr 25 '07 #10

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

Similar topics

9
by: Giulio | last post by:
why definition of two constructors like these is not possible in c++??? ----------------------- date::date(const int d, const int m, const int y, const int ora, const int mi, const int se){...
7
by: Robin Forster | last post by:
I have two classes: aule_gl_window (parent class) and aule_button (sub class) I want to call the super class (parent) constructor code from the sub class constructor.
34
by: Asfand Yar Qazi | last post by:
Hi, I'm creating a library where several classes are intertwined rather tightly. I'm thinking of making them all use pimpls, so that these circular dependancies can be avoided easily, and I'm...
7
by: John Salmon | last post by:
I'm working with two libraries, one written in old school C, that returns a very large chunk of data in the form of a C-style, NUL-terminated string. The other written in a more modern C++ is...
84
by: Peter Olcott | last post by:
Is there anyway of doing this besides making my own string from scratch? union AnyType { std::string String; double Number; };
10
by: JurgenvonOerthel | last post by:
Consider the classes Base, Derived1 and Derived2. Both Derived1 and Derived2 derive publicly from Base. Given a 'const Base &input' I want to initialize a 'const Derived1 &output'. If the...
22
by: clicwar | last post by:
A simple program with operator overloading and copy constructor: #include <iostream> #include <string> using namespace std; class Vector { private: float x,y; public: Vector(float u, float...
50
by: Juha Nieminen | last post by:
I asked a long time ago in this group how to make a smart pointer which works with incomplete types. I got this answer (only relevant parts included): ...
14
by: Sweeya | last post by:
/*Program to do manipulations on a string*/ #include <iostream> using namespace std; class String { int len; char *p;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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: 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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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
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...

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.