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

What is the second const used for?

I have searched and not found an answer to this question. I ran upon
the following statement in a *.cpp file in a member function:

static const char * const pacz_HTMLContentTypeHeader = "Content-Type:
text/html\r\n";

Why is the second const needed and what does it do?

Thanks

Gary

Feb 7 '07 #1
4 6653
gr*****@yahoo.com wrote:
I have searched and not found an answer to this question. I ran upon
the following statement in a *.cpp file in a member function:

static const char * const pacz_HTMLContentTypeHeader = "Content-Type:
text/html\r\n";

Why is the second const needed and what does it do?
'const' makes the adjacent type constant. In your case, the 'const'
between 'static' and 'char' makes 'char' constant (immutable). The
other 'const' (right after the asterisk) makes the adjacent type
(which is 'a pointer to const char') immutable.

The other way is to learn to read declarations. In your case the
object 'pacz_HTMLContentTypeHeader' is [going to the right, seeing
the end of the declaration, proceeding to the left] a const [the
asterisk] pointer to char [which is] const, and the lifetime is
static.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Feb 7 '07 #2
Here is an explanation on const that I created for my C++ students (it
should answer most of your const questions):

The purpose of the const keyword is to prevent accidental or
unintentional change of a value.

Let us examine some examples of using the const keyword and the types
of errors that will be generated, if we try to circumvent the
protection offered by the const keyword. Note that all error messages
displayed were generated by MS Visual Studio .NET 2003.

Example 1:

const int x = 10; // const protects x from being modified.
// x must be initialized, or a compile error
// will be generated.
x = 5; // This is NOT allowed. Compiler error generated follows below.

error C2166: l-value specifies const object
Example 2:

// Note that this function does not actually modify y
void func(int & y)
{
return;
}

int main()
{
const int x = 10; // const protects x from being
// modified.
func(x); // This is NOT allowed.
}

error C2664: 'func' : cannot convert parameter 1 from 'const int' to
'int &'

This error is generated because func() is not "promising" to not
change x's value. It does not matter that the function does not
actually change x's value.

If the function prototype was instead:

void func( const int & y); // or
void func( int const & y); // the order of const and int does not
// matter

there would be no compile error. Now the function is promising to not
change x's value through the use of the const keyword.

This is another reason why we should attempt to make parameters of a
function const, so that the function can accept both const and non-
const arguments.

If the function prototype was instead:

void func( int y);

there would also be no compile error. Why? Because now y is being
passed call by value, rather than call by reference, so we don't care
if the function changes the argument.

Example 3:

int x = 10;
int y = 20;
const int *xPtr; // may NOT use pointer to modify value, but may
// let pointer point to another address

xPtr = & x; // this is allowed
xPtr = & y; // and this is allowed as well

*xPtr = 50; // This is NOT allowed. Attempting to dereference
// the pointer and change the value at that address.

error C2166: l-value specifies const object
Example 4:

int x = 10;
int y = 20;
int * const xPtr = &x; // may use pointer to modify value, but
// may NOT let pointer point to another address

xPtr = & y; // This is NOT allowed.

*xPtr = 50; // But this is allowed.

error C2166: l-value specifies const object

Notice that in this example, xPtr must be initialized when it is
declared, while in the previous example it was not necessary to do so.

Example 5:

int x = 10;
int y = 20;
const int * const xPtr = &x; // may NOT use pointer to modify
// value, and may NOT let pointer point to another address

xPtr = &y; // This is NOT allowed

*xPtr = 50; // This is NOT allowed either

error C2166: l-value specifies const object
error C2166: l-value specifies const object

This last example is simply Example 3 & 4 combined.

Note that in the following function prototype, zPtr is being offered
the exact same protection as xPtr in the above example.

void func( const int * const zPtr);

Do you think the xPtr from above could be passed to a function with
the following prototype?

void func(const int * iPtr);

Yes it can! Surprised? It is because, similar to what was discussed in
Example 2 above, iPtr is being passed call by value. Now, if instead
we had the following function prototype.

void func(const int *& iPtr);

Now iPtr is being passed call by reference, and therefore the compiler
would complain if we tried to pass xPtr to this function. Of course
xPtr could be passed to the following function with no problem.

void func(const int * const & iPtr);

Example 6:

class myClass {
public:
void memFunc(myClass & obj2) const // This const protects the
// object invoked with this method.
{
obj2.dataMem = 10; // Object obj2 is not protected by
// making memFunc() const. No error will be generated.
this->dataMem = 10; // This is NOT allowed.
}
private:
int dataMem;
};

int main()
{
myClass x,y;
x.memFunc(y);
return 0;
}

error C2166: l-value specifies const object
Example 7:

class myClass {
public:
const int & memFunc(int & iRef) // This const protects the
// reference being returned by the method.
{
return iRef;
}
private:
int dataMem;
};

int main()
{
int y;
myClass x;
x.memFunc(y) = 10; // This is NOT allowed. We are trying to
// change the reference being returned by memFunc().
return 0;
}

error C2166: l-value specifies const object

Would the following change to main() also generate an error?

int & z = x.memFunc(y);

The answer is yes! Not because we are trying to modify the reference
returned by memFunc(), but because we are assigning that reference to
another reference which is not const. The following statement would
be ok.

const int & z = x.memFunc(y);

Now z is a const reference, and is "promising" to not modify the const
reference being assigned to it.

Would the following statement also generate an error?

int z = x.memFunc(y);

No. In this case, only a copy of the reference being returned by
memFunc() is assigned to z. Modifying z will not modify the reference
which was returned by memFunc().
Example 8:

This example is actually an extension of Example 2.

void func(const int & val) // This const protects val from being
// modified inside this function.
{
val = 20; // This is NOT allowed.
}

int main()
{
int x =10;
func(x);
return 0;
}

error C2166: l-value specifies const object

In case you are wondering, even if val were passed to func() as a call
by value rather than as a call by reference, val may still NOT be
modified inside of func().

Example 9:

class myClass {
public:
myClass (void) { //default ctor
this->year = 1970;
this->month = 1;
this->day = 1;}
myClass (int y, int m = 1, int d = 1){ // conversion ctor
this->year = y;
this->month = m;
this->day = d; }

void memFunc (){} // non const member function does nothing

private:
int year;
int month;
int day;
};

int main()
{
const myClass defaultObj; // use default ctor
// to create const object
const myClass bDay(1956,04,25); // create a second const object

defaultObj.memFunc();// This is NOT allowed since
// memFunc() is not const
bDay.memFunc();// This is NOT allowed since
// memFunc() is not const

return 0;
}

error C2662: 'myClass::memFunc' : cannot convert 'this' pointer from
'const myClass' to 'myClass &'

error C2662: 'myClass::memFunc' : cannot convert 'this' pointer from
'const myClass' to 'myClass &'

If we wish to create a const object of a user defined class, we must
have a constructor that can initialize the object exactly as we need
it to be, since we will not be able to modify the object after it has
been "constructed".

Note that in the sample code above, if we had declared the 3 data
members to be public instead of private, we would still not have been
able to change the value of the members of the defaultOBJ and bDay
objects in main(), because these objects are const.
Miscellaneous Point 1:

The following will generate some compile errors.

int main()
{
int SIZE = 10; // SIZE is not const
int y[SIZE]; // SIZE is not a constant, so NOT allowed.
return 0;
}

If we make SIZE const, the compiler is now happy.

int main()
{
const int SIZE = 10; // SIZE is now const
int y[SIZE]; // SIZE is now a constant, so it is allowed.
return 0;
}
Miscellaneous Point 2:

We are normally not allowed to initialize a data member inside a class
declaration in C++. One exception is a const static data member of
integral type. By integral type we mean types char, short, int, long
or long long. Type double for example is NOT an integral type. Below
is a code snippet showing a valid example:

class myClass {
private:
const static int SIZE = 100; //class variable
int dataArray[SIZE]; //use class variable declared and
// initialized in previous statement
...

Again, I stress that the above example works only because SIZE is
static, const and an integral type.

Miscellaneous Point 3:

What is wrong with the following code example?

class myClass {
public:
int & memFunc(const int & iRef)
{
return iRef;
}
private:
int dataMem;
};

int main()
{
const int y = 10;
myClass x;
x.memFunc(y);
return 0;
}

Here is a hint. This code will generate the following compile error.

error C2440: 'return' : cannot convert from 'const int' to 'int &'

The problem is that memFunc() is trying to return iRef as a non const
reference. To make the error go away, we must either return a non
reference or make the returned reference const.
That pretty well covers my introduction to the use of const. Remember
that one of the traits of a good C++ programmer is that they use const
where ever possible in their code. In the long run, such a practice
will pay real dividends.

Feb 7 '07 #3
Victor Bazarov wrote:
gr*****@yahoo.com wrote:
>I have searched and not found an answer to this question. I ran upon
the following statement in a *.cpp file in a member function:

static const char * const pacz_HTMLContentTypeHeader = "Content-Type:
text/html\r\n";

Why is the second const needed and what does it do?

'const' makes the adjacent type constant. In your case, the 'const'
between 'static' and 'char' makes 'char' constant (immutable). The
other 'const' (right after the asterisk) makes the adjacent type
(which is 'a pointer to const char') immutable.

The other way is to learn to read declarations. In your case the
object 'pacz_HTMLContentTypeHeader' is [going to the right, seeing
the end of the declaration, proceeding to the left] a const [the
asterisk] pointer to char [which is] const, and the lifetime is
static.
Or to simplify, the first const says you can't modify the char data
through pacz_HTMLContentTypeHeader, and the second const says you can't
change *where* pacz_HTMLContentTypeHeader points to.
Feb 7 '07 #4
gr*****@yahoo.com wrote:
I have searched and not found an answer to this question. I ran upon
the following statement in a *.cpp file in a member function:

static const char * const pacz_HTMLContentTypeHeader = "Content-Type:
text/html\r\n";

Why is the second const needed and what does it do?
Here is a (very) succint summary of const as it applies to pointers:
http://www.parashift.com/c++-faq-lit....html#faq-18.5

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Feb 8 '07 #5

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

Similar topics

9
by: John Cho | last post by:
// CHO, JOHN #include<iostream> class fracpri{ int whole; int numer; int denom;
3
by: user | last post by:
What's the meaning of these two lines? extern const double __infinity; #define INFINITY __infinity
10
by: tjgable | last post by:
I have some code that builds fine on .Net 2001(?).. VC++ 7.0. But with gcc 3.42 in MinGW and MS VC++ 6.0 it does not. I can understand VC++ not working, but isn't gcc standard yet? Here is the...
14
by: howa | last post by:
void reverse_string(char *str) { if (str == NULL) return; char tmp; size_t len = strlen(str); size_t mid = (int) len / 2; for (size_t i = 0; i < mid; i++) {
5
by: Phil Ward | last post by:
The following has recently arose and it is the first time I have noticed this behaviour. I have been using a self-defined string class. It's form is class CMyString { public: ... (no public...
3
by: Grizlyk | last post by:
Hello. I am thinking: why if i will comment lines marked with '#' in the following example, all will be compiled, else will not: // *********************** typedef unsigned uint; ...
4
by: desktop | last post by:
I found this class at: http://www.icce.rug.nl/documents/cplusplus/cplusplus17.html#FINDEND class Twice { public: bool operator()(size_t first, size_t second) const { return first ==...
6
by: Peter Lee | last post by:
what's the correct behaver about the following code ? ( C++ standard ) I got a very strange result.... class MyClass { public: MyClass(const char* p) { printf("ctor p=%s\n", p);
5
by: Vols | last post by:
class A{ public: int x; }; class B : public A{ public: int y; }; void foo()
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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...

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.