# Question on this overload program

Staff Emeritus
. It seems very likely to me that the std namespace has a definition for something called size, and the compiler can't tell which one you mean: the size in the std namespace or the size that you have defined.

You are correct.

yungman
Sure it is -- it compiles without error and it runs and produces correct results.

Here's from my class definition:
C++:
#include <iostream>
#include <cstring>

using std::cout; using std::endl;
using std::ostream;
const int SIZE = 25;

class ThreeVector
{
private:
double x, y, z;
char name[SIZE];
int serialNum;          // unique for each ThreeVector instance
static int numVectors;  // counts the number of ThreeVectors constructed
... <public members>

A possible reason for the problem you're seeing is that you have using namespace std;
I said a long time ago that bringing the whole namespace in like this is a bad idea. It seems very likely to me that the std namespace has a definition for something called size, and the compiler can't tell which one you mean: the size in the std namespace or the size that you have defined.
Oh my god, you are correct. I never thought about that. Now I can at least move on. Never thought namespace std caused so much problem.

Thanks a million.

Homework Helper
Gold Member
really test out how much I really understand this.
Here's a test:

Q1. Explain using the terms 'declaration' (or declare) and 'initialisation' (or initialise) why this code does not make sense:
C++:
const int size;

Q2. Give 2 reasons why this code doesn't work:
C++:
char name[25];
name[25] = "alan";

I am looking at your code, it doesn't seem to me that it's better than my very first post.
Sure it is -- it compiles without error and it runs and produces correct results.

Mark44
Staff Emeritus
I said a long time ago that bringing the whole namespace in like this is a bad idea.

Yes you did. However, I think there are degrees of badness:

C++:
#include<iostream>
using namespace std;
int main() {
cout << "Test.\n";
return(0);
}

is very bad, because it infects everything.

C++:
#include<iostream>
int main() {
using namespace std;
cout << "Test.\n";
return(0);
}

is better, because it only infects main(). In a subroutine, this is better. In a member function, better still.

C++:
#include<iostream>
int main() {
using std::cout;
cout << "Test.\n";
return(0);
}

is even better still, because it brings in only the one needed element, so the odds of a collision go way down.

yungman
Here's a test:

Q1. Explain using the terms 'declaration' (or declare) and 'initialisation' (or initialise) why this code does not make sense:
C++:
const int size;

Q2. Give 2 reasons why this code doesn't work:
C++:
char name[25];
name[25] = "alan";

First question, it was a mistake, somehow I deleted it when I copied over.
Second is easy, I just learn it today. Need to use strncpy_s(name, 25, "alan", 25).

Mentor
Q2. Give 2 reasons why this code doesn't work:
C++:
char name[25];
name[25] = "alan";
Second is easy, I just learn it today. Need to use strncpy_s(name, 25, "alan", 25).
No, you didn't answer what @pbuk asked you to do, which was to give 2 reasons why that code doesn't work. He didn't ask you to do it another way.

yungman
No, you didn't answer what @pbuk asked you to do, which was to give 2 reasons why that code doesn't work. He didn't ask you to do it another way.
Yes I did! First one I forgot the 25. the second one is using the wrong =, can't do that with c-strings. Isn't that obvious?

Mentor
You can define your const int size = 25 inside the class, as member data, but you have to make it static, presumably because that value is intended to be shared among all the instances of the class.
C++:
class Vec
{private:
int x, y, z;
static const int size = 25;
char name[size];
// etc.
};
Hmmm... when I try to make it non-static (const int size = 25;), g++ gives me merely a warning message, not an error: in-class initialization of non-static data member is a C++11 extension.

Which version of C++ does VS default to? It might depend on which version of VS you're using.

yungman
yungman
You can define your const int size = 25 inside the class, as member data, but you have to make it static, presumably because that value is intended to be shared among all the instances of the class.
C++:
class Vec
{private:
int x, y, z;
static const int size = 25;
char name[size];
// etc.
};
Hmmm... when I try to make it non-static (const int size = 25;), g++ gives me merely a warning message, not an error: in-class initialization of non-static data member is a C++11 extension.

Which version of C++ does VS default to? It might depend on which version of VS you're using.
I am glad you are here. This is an extension YOUR thread! I just don't want to hijack your thread so I started my own. My VS is 2019.

To me, your thread was quite clear on what steps the compiler was doing. I carried on one step more, I want to look when I give a c-string to the class, I want to see how it is being copied. I am not convinced at all that there is a solution to copy the c-string over yet. In the very first post, I showed the name is not passed from what you called Vector#4(sum) to Vector#5(some temporary). There is a miss connection there and I got garbage when I print out the c-string of Result( which is your c).

About the "size", this has been resolved thanks to Mark. I just don't use using namespace std. Or maybe changing the name size.

Thanks

Last edited:
yungman
Apparently I still running into issue of passing c-string as parameter. Here is the very short program and you can see one way works and the other doesn't:
C++:
#include <iostream>
#include <cstring>
using std::ostream;
using std::cout; using std::endl;
const int size = 25;
class Vec
{private:
int x, y;
char name[size];
public:
Vec(int x0, int y0, char *desc)
{ x = x0, y = y0;
strncpy_s(name, size, desc, size);
}
};
int main()
{    char vecA[size] = "vecA";
Vec a(1, 2, vecA);//This works
Vec b(2, 4, "vecB");//This doesn't work.
return 0;
}

Line 20 just won't work. Why?

Thanks

Mentor
Line 20 just won't work. Why?

No, you still didn't answer what @pbuk asked you to do, which was to give 2 reasons why the code below doesn't work.
C++:
char name[25];
name[25] = "alan";

the second one is using the wrong =, can't do that with c-strings. Isn't that obvious?
If that's the wrong =, is there another = that works? What's your second reason?

Mentor
Line 20 just won't work. Why?
See post #67.
To elaborate a bit on the statement in post #67:

A literal string such as "vecB" doesn't have type char *. It implicitly has type const char *, because it makes no sense to change the value of a literal string.

You can't pass a const char * to a function that declares a parameter to be char *. When you declare a parameter without specifying const, it signals to the compiler that the function might change the value of the parameter.

Therefore, if you want to be able to pass a literal string to a function, you must declare the parameter as const char *.

(On the other hand, you can pass a char * (e.g. a char array that isn't declared as const) to a function that declares a parameter as const char *.)

[oops, yungman quoted this while I was editing it for clarity.]

Last edited:
yungman
yungman
To elaborate a bit on the statement in post #67:

A literal string such as "vecB" doesn't have type char *. It has type const char *.

You can't pass a const char * to a function that declares a parameter to be char *. When you declare a parameter without specifying const, it signals to the compiler that the function might change the value of the parameter. However, it makes no sense to change the value of a literal string, so those are always implicitly const char *.

(On the other hand, you can pass a char * (e.g. a char array that isn't declared as const) to a function that declares a parameter as const char *.)
THANK YOU
This is what I need. I have not seen any explanation on this before. That's why I make mistake and don't even know why. Whole day today has been tripped by the c-string copying and passing parameter. this definitely will be in my notes.

that's why when I read Marks reply again, I still didn't understand until your post just pop up! Just like in your thread, everyone replied sounded like they think everyone knew all that, that was NEW to me, that was an eye opener! That's why I spent over a week now on your post and I refuse to move on until I get everything to learn out of it.

Actually I am in the process of writing out the program without looking at any of the stuff, line by line reasoning out, step by step doing it again.

Thanks

Mentor
You might want to check the revised version of my post. I was in the middle of editing it when you quoted it. I didn't change the main point, just tried to make it clearer (hopefully).

yungman
You might want to check the revised version of my post. I was in the middle of editing it when you quoted it. I didn't change the main point, just tried to make it clearer (hopefully).
Can you tell me which post #?

thanks

Mentor
Actually I am in the process of writing out the program without looking at any of the stuff
Read through this thread before you start writing out the program. At the very least, doing so might eliminate more questions that we've already answered.

yungman
I did it. My biggest road block is about the passing and copying c-string. After learning all those today thanks to Mark and Jtbell, it is very smooth to write my own. I wrote the whole program with very little peeking to the existing programs. It is actually different enough from Jtbell's. I think I understand Jtbell's thread, I am ADDING to the program and remove some of the stuffs like the Vector# and z. I am concentrating on passing the c-string around and make sure it's not shallow copying. I did it!

I actually think about what I was writing to write the code, why I put const in front of the variable types like const char*. I got it done quite fast. this is my program:
C++:
#include <iostream>
#include <cstring>
using std::ostream;
using std::cout; using std::endl;
const int size = 25;
class Vec
{private:
int x, y;
char name[size];
public:
Vec(){ x = 0, y = 0;
strncpy_s(name, size, "Default", size);
cout << " [In Dconstructor], object created: " << name <<
"(" << x << "," << y << ")   address: " << this << "\n\n";
}
Vec(const char*desc) { x = 0, y = 0;
strncpy_s(name, size, desc, size);
cout << " [In Constructor], object created: " << name <<
"(" << x << "," << y << ")   address: " << this << "\n\n";
}
Vec(int x0, int y0, const char *desc){ x = x0, y = y0;
strncpy_s(name, size, desc, size);
cout << " [In Constructor], object created: " << name <<
"(" << x << "," << y << ")   address: " << this << "\n\n";
}
Vec(const Vec& original)
{    x = original.x; y = original.y;
strncpy_s(name, size, "Temp", size);
cout << " [In Copy Constructor], object created: " << name <<
"(" << x << "," << y << ")   address: " << this << "\n\n";
}
Vec operator+(const Vec& right)
{  Vec sum;
sum.x = x + right.x; sum.y = y + right.y;
strncpy_s(sum.name, size, "sum", size);
cout <<" [In OP+]: " << sum.name << "(" << sum.x << "," << sum.y <<
") = " << (*this).name <<"(" << (*this).x << "," << (*this).y <<
") + " << right.name <<"(" << right.x << "," << right.y << ")\n\n";
return sum;
}
Vec& operator=(const Vec& rhs)
{x = rhs.x; y = rhs.y;
strncpy_s(name, size, rhs.name, size);
cout << " [In OP=]: " << rhs.name << "(" << rhs.x << "," << rhs.y <<
")   is copied into   " << name << "(" << x << "," << y << ")\n\n ";
return *this;
}
friend ostream& operator<<(ostream& out, const Vec& v)
{out << " [OP<<] c contains: " << v.name << "(" << v.x << "," << v.y << ")\n\n"; return out; }
};

int main()
{    Vec a(1, 2, "vecA");
Vec b(3, 4, "vecB");
Vec c("vecC");
c = a + b;
cout << c << "\n\n";
return 0;
}

Attached is the print out. I checked the address where the compiler go step by step.
I intentionally let "Temp" to copy over to object c so when I display c, I get Temp(4,6). This is by intention to show I successfully pass the literal c-string in every step.

Thanks everyone for the help. I am going to look at Mark's program and make it work tomorrow. I learn so much out of this exercise, it's a week of hard work worth while. I don't think I can do nearing half if I stick to the book. Now I feel good about the overloading operator a lot better than last week.

Thanks a million to everyone that helped me.

#### Attachments

• Alan version of Jtbell program.docx
11.8 KB · Views: 83
yungman
@yungman, regarding the problem you were trying to solve when you opened this thread (adding a C-string name field to the class), here are some pieces of my solution. The code is based on what @jtbell posted.
The class definition, in what I'm calling ThreeV.h:
C++:
#include <iostream>
#include <cstring>

using std::cout; using std::endl;
using std::ostream;
const int SIZE = 25;

class ThreeVector
{
private:
double x, y, z;
char name[SIZE];
int serialNum;          // unique for each ThreeVector instance
static int numVectors;  // counts the number of ThreeVectors constructed
public:
ThreeVector();                        // default constructor
ThreeVector(double, double, double, const char*);
ThreeVector(const char* name);
ThreeVector(const ThreeVector&);      // copy constructor
~ThreeVector();
ThreeVector operator+ (const ThreeVector&) const;
ThreeVector& operator= (const ThreeVector&);
friend ostream& operator<< (ostream& out, const ThreeVector& v);
};
A couple of the function definitions, in the same file:
C++:
// Default ctor
ThreeVector::ThreeVector()
{
x = 0;  y = 0;  z = 0;
strncpy_s(name, SIZE - 1, "Default", SIZE - 1);
numVectors++;
serialNum = numVectors;
cout << "-- Default-constructed vector #" << serialNum << endl;
}
// Another ctor
ThreeVector::ThreeVector(double x0, double y0, double z0, const char * str)
{
x = x0;  y = y0;  z = z0;
strncpy_s(name, SIZE-1, str, SIZE - 1);
numVectors++;
serialNum = numVectors;
cout << "-- Constructed vector #" << serialNum << endl;
}

ThreeVector ThreeVector::operator+ (const ThreeVector& rhs) const
{
ThreeVector sum("Sum");
sum.x = x + rhs.x;  sum.y = y + rhs.y;  sum.z = z + rhs.z;
cout << "Return from operator+..." << endl;
return sum;
}
Not shown are
• a constructor that initializes the name portion with a specified string, and initializes the other data members to 0
• a copy constructor
• the destructor (same as jtbell posted)
• overloaded operator<<() (same as jtbell posted)
The class consumer:
C++:
#include <iostream>
#include "ThreeV.h"
using std::cout; using std::endl;

int main()
{
cout << "Declare a and b..." << endl;
ThreeVector a(1, 2, 3, "VecA"), b(4, 5, 6, "VecB");
cout << "a: " << a << " b: " << b << endl;
cout << "Declare c and add c = a + b..." << endl;
ThreeVector c;
ThreeVector d("VecD");
cout << "c: " << c << " d: " << d << endl;
c = a + b;
cout << "c: " << c << endl;
cout << "Return from main()..." << endl;
}`

Hi Mark

I look through your program one more time. I hope I don't offend you, I think you missed my point from my first post. I have no problem printing out name of a, b and c( in your program is vecA, vecB and vecC) right from the beginning. If you look at my first post and the print out, you would see I got those already. My issue is the name in Temp got lost when copy from sum to Temp and thereby getting garbage in the final Result(which is vecC in your program).

You only provided the part that I already did in my very first post by constructors with names. ( I use name = new char[]). My question are ALL in Copy Constructor and operator=() which you have not addressed. That's what I was working on through out the whole thread here. that's why when you ask me to work with your program, I already kind of know that's not it already.

But I thank you for getting me through the issue of copying c-string and passing c-string as parameter using const char*desc. It turn out that's all the problem with me. After I understand from you and Jtbell, I have no issue writing the program one time through tonight. Now I proof I can write program with these few operators and constructors.

If you look at my final program, I actually copy the name from sum and change to Temp, then actually overwrite vecC to Temp in c step by step. When I print out c, I actually get Temp to proof I actually passing the c-string name over. It doesn't make sense, BUT that's what I set out to do in the very first post. This conclude my questions in this thread.

Thanks you so much for your help and patience. This thread is so important for me to understand deeper into overloading and more importantly, learn to look at how the compiler think.

Thanks

Mentor
Can you tell me which post #?

thanks
The one you were replying to... #82.

yungman
yungman
The one you were replying to... #82.
Oh good!, I need to edit my notes, I literally copy part of your post 82 into my notes. I thought you were talking about in your thread.

Thanks