Consider the following C++ code:
// friend functions
#include <iostream>
using namespace std;
class CRectangle {
int width, height;
public:
void set_values (int, int);
int area () {return (width * height);}
friend CRectangle duplicate (CRectangle);
};
void CRectangle::set_values (int a, int b) {
width = a;
height = b;
}
CRectangle duplicate (CRectangle rectparam)
{
CRectangle rectres; // Defined without using new keyword. This means scope of this variable of in this function, right ?
rectres.width = rectparam.width*2;
rectres.height = rectparam.height*2;
return (rectres);
}
int main () {
CRectangle rect, rectb;
rect.set_values (2,3);
rectb = duplicate (rect);
cout << rectb.area();
return 0;
}
The variable "CRectangle rectres" is defined in the function "CRectangle duplicate".
Does this mean that the scope of the variable "CRectangle rectres" is limited to the function only ? (since it has been defined without using new keyword)
If answer to above question is yes, then how can it be returned (since it is a local variable) ?
Credits : Code take from : http://www.cplusplus.com/doc/tutorial/inheritance/
Your question as to 1 & 2 has been adequately answered by Patrick, but I thought I could expand a bit:
The way MOST compilers work [1] when you return a struct or class object is that the calling function passes in a pointer argument (that is hidden from view) for the "return here" value. So the called function will copy the result into the place supplied by the calling code - the actual copy is done by the copy constructor of the class.
note 1: that the C++ standard doesn't say how the compiler should do this, and if the compiler can produce magical code that just moves the bits by using "The Force" from Star Wars then that is also allowed according to the standard.
Yes, it is a local variable.
If you return a copy of rectres
Related
I'm learning C++.
Came across data encapsulation and data hiding at a website, check out the following piece of code:
#include<iostream.h>
#include<conio.h>
class sum {
private: int a, b, c;
public:
void add() {
clrscr();
cout << "Enter any two numbers: ";
cin >> a >> b;
c = a + b;
cout << "Sum: " << c;
}
};
void main() {
sum s;
s.add();
getch();
}
NOW. As it says here that:
The main advantage of using of encapsulation is to secure the data from other methods, when we make a data private then these data only use within the class, but these data not accessible outside the class.
What happens underneath the code, what does the compiler do that makes it inaccessible to other classes? And in the given example what was the reason behind defining a,b and c as private.
What were they trying to achieve by hiding "just the declarations of the three variables"? Because anyone can see that inside public three numbers being used are a,b, and c - first two for input and third one for output.
How is this possible that the data under private can't be accessed
outside the class?
Compiler makes sure you don't. If you try to access say a outside class, your code will not compile.
And in the given example what was the reason behind defining a,b and c
as private.
It could be anything! But as a result, a,b and c are not accessible outside members of class.
Basically you want to hide some variables in your class for the sake of consistency. So that you or your clients can not produce a code that makes unwanted and uncontrolled changes.
Updates:
What happens underneath the code, what does the compiler do that makes
it unaccessible to other classes?
Compiler implementation check for access level while producing code. If there is something wrong, you will get a syntax error and no machine code will be generated from your file.
And in the given example what was the reason behind defining a,b and c
as private; what were they trying to achieve by hiding "just the
declarations of the three variables"? Because anyone can see that
inside public three numbers being used are a,b, and c - first two for
input and third one for output.
You don't hide variables in your class to make them invisible to others. Private variables that are not intended to be used from outside of the class can be marked as private to limit the potential for coding errors.
As an example consider following class:
class rectangle {
public:
int width;
int height;
int area;
};
void something_important(const rectangle& r) {
// ...
}
What happens if I pass a rectangle of width -10, height 0 and area of -15? There could be a plane crash or a nuclear weapon launched to some wrong target... So I will make sure my rectangles are always valid:
class rectangle {
public:
void set_width(int w) {
if(w) width = w;
else width = 0;
area = width*height;
}
int get_width() const {return width;}
void set_height(int h) {
if(w) height = h;
else height = 0;
area = width*height;
}
int get_height() const {return height;}
int get_area() const {return area;}
private:
int width;
int height;
int area;
};
So no one can make a rectangle of negative height or width, and no one can make a rectangle having a wrong area. (you can not actually change area directly)
I hope it makes sense for you now.
What happens underneath the code, what does the compiler do that makes it unaccessible to other classes?
Not much. The compiler doesn't protect against access to the data. It protects against access to the name of the data. For instance:
void foo(class bar&, int&);
class bar {
int i = 0;
public:
void baz() {
foo(*this, i);
}
};
void foo(class bar& b, int& i) {
//b.i = 42; // This is an error. b.i is private
i = 42; // This is okay, no matter what the local i refers to
}
In the example above, foo() cannot access b.i by name, because it's a private data member. But it can still modify it if it obtains a reference by other means. The member function baz() which has access to that name, binds it to the reference that foo() accepts. Thus allowing for its modification from outside the class's scope.
I am not sure why my function is not working. It should be printing out something out (an error message after the user goes out of bounds)I have set the array index at 3 index slots. I'm also getting an error "unused variable 'yourArray' I am not sure where to go from here. Still trying to learn c++ so and advice or help will be greatly appreciated.
#include <iostream>
using namespace std;
class safeArray{
public:
void outofBounds(int,int);
int yourArray[3];
int i;
};
void outofBounds(int,int);
int yourArray[3];
int i;
void outofBounds(int yourArray[],int sizeofArray) {
for (i=0;i<sizeofArray;i++){
cout<<"Please enter integer";
cin >>yourArray[i];
yourArray[i]++;
for (i=0;i>sizeofArray;){
cout<<"safeArray yourArray (" <<yourArray[0]<<","<<yourArray[3]<<")"
<<endl;
}}}
int main() {
void outofBounds(int,int);
int yourArray[3]; //Error: Used variable "yourArray"
};
Your Program is running fine. Unless you added the "-Werror" flag to the compiler, which would treat the "unused variable"-Warning as an Error.
The code compiles fine as seen on here: http://coliru.stacked-crooked.com/a/d648b94f205b51dc
Though your Program does not do what you want it to do, because of the following reasons:
1.) You have 3 redefinitions of outofBounds inside different namespaces:
one inside the classes namespace SafeArray which is a member function
of it
then inside the global space
and then inside the main-function (the entry point)
But the one being actually defined is the one in the global space (2nd one)
2.) You are not passing anything to the function inside main.
define your Array there first then call the function by doing:
int yourArray[3];
outofBounds(yourArray, 3);
3.) You probably wanted to define the member method "outofBounds" inside SafeArray-class. This can be done by writing the scope operator:: which specifies the class to which the member function belongs to:
class SafeArray { // is a class, can also be struct since everything is public anyways
public:
void outofBounds(int,int); // a member of the class SafeArray
// private:
int yourArray[3];
int i;
};
void SafeArray::outofBounds(int yourArray[],int sizeofArray) {
// do something...
}
but then again you need some constructor that initializes the members of your class. Some work needs to be done to make it work, like you want. Good Luck :)
I am new to C++. I have this code to create a struct, to show the usage of mutable keyword in C++.
#include <iostream>
using namespace std;
int main()
{
struct
{
mutable double radius;
double PI = 3.142;
double getArea()
{
return (PI * radius * radius);
}
} circle;
const struct circle c1 = {2.0};
circle.radius = 7;
cout << "Area is " << circle.getArea() << endl;
return 0;
}
But I get the following error message when compiling:
error: variable const main()::circle c1 has initializer but incomplete type
Error is at c1 in the line const struct circle c1 = {2.0};. Can anyone point me out the error here.
You don't define a structure named circle, you define a variable named circle. This variable can not be used as a type.
You should do e.g. struct circle { ... }; to define the structure as a type. Then you could do
const circle c1 = { 2.0 };
c1.radius = 7;
std::cout << c1.getArea() << '\n';
There are a few other problems, most notable you don't declare the getArea function as const which means you can't call it on const objects.
When you put the name circle after the right brace at the end of the struct definition, you're declaring a variable.
Put it at the start, after the word struct, to declare a type.
I.e.
struct circle
{
// ...
};
In other news:
You'll need to declare getArea() as const to be able to call it on a const instance, i.e. double getArea() const.
You don't need the return 0; at the end, because that's the default for main. There is no such default for other functions. main is special.
In order to use cout unqualified (as it seems you want to) you can add using namespace std; at the start of the code; it's usually placed after the includes.
mutable is usually not used to allow outside code to treat part of an object as always non-const.
Instead it's used as a device to more easily let a class implementation have some non-const state also when the object appears to be const to outside code. That's called logical constness. For example, the object might cache the result of an expensive computation, even when it's const.
In C++17 and later mutable can also be applied to lambda expressions, where it yields a lambda that can change its state (captured values).
I'll try to make this as concise as possible and while I understand that these questions can be considered "basic" I have already looked at websites such as cplusplus.com and yolinux tutorials but i need somebody to explain this to me like I have just had a major head trauma..
1)
class Rectangle {
private:
int lineNumber; // LineNumber of the ACSIL Tool
float valueMax; // value of the higher limit of the rectangle
float valueMin; // value of the lower limit of the rectangle
public:
Rectangle(SCStudyInterfaceRef sc, int lineNumber, float valueMax, float valueMin);
int getLineNumber();
float getValueMax();
float getValueMin();
};
So int linenumber, valueMax and ValueMin are declared private members and thus are only accessible by members of the same class, thats fine. But what about the part that follows the "public:" ?
a) Is Rectangle(SCStudyInterfaceRef sc, int lineNumber, float valueMax, float valueMin); a function that is being overloaded? and if yes are int getLineNumber() etc part of that function or seperate members of the public part of the class?
2)
Rectangle::Rectangle(SCStudyInterfaceRef sc, int lineNumber0, float value1, float value2) {
lineNumber = lineNumber0;
int value2_greater_than_value1 = sc.FormattedEvaluate(value2, sc.BaseGraphValueFormat, GREATER_OPERATOR, value1, sc.BaseGraphValueFormat);
if (value2_greater_than_value1 == 1) {
valueMax = value2;
valueMin = value1;
} else {
valueMax = value1;
valueMin = value2;
}
}
int Rectangle::getLineNumber() {
return lineNumber;
}
float Rectangle::getValueMax() {
return valueMax;
}
float Rectangle::getValueMin() {
return valueMin;
}
a) I'm pretty sure that the functions defined inside the public part of the rectangle class are being "defined" here, or something along those lines.
b) I am really confused about what is happening here on the Rectangle::Rectangle(SCStudyInterfaceRef sc, int linenumber0, float value1, float value2) part. I understand the logic of what is happening within the function itself but i am confused about the paramters being input within the " ( ) " and how exactly this relates to what happenes inside the class public part. This really is the most important question that needs answering.
I have tried to be as concise and onpoint as possible, would appreciate some help in understanding this syntax.
Question 1
It's a constructor with 4 parameters.
int getLineNumber();
float getValueMax();
float getValueMin();
are all member functions in the class.
Question 2
The constructor defined earlier is called with 4 parameters. If no other constructor is defined then you'll have to instantiate the class with exactly 4 parameters, i.e:
Rectangle *rect = new Rectangle(sc, 100, 1.2, 6.8);
or simply:
Rectangle rect(sc, 100, 1.2, 6.8);
These parameteres are then used to "set the object in an initial state".
The member functions are used to get various values in their current (or final or only) state.
Rectangle::Rectangle is the class constructor. It is called whenever a Rectangle object is created. Read about constructors to understand better.
The constructor is setting initial values for the valueMax and valueMin member variables. It uses the parameters passed to the constructor to do this. Read about function parameters to understand better.
1) a: If no ctor function is declared, then the compiler writes a ctor for the class. But when a ctor is provided by the class no default ctor is written by the class and hence no overloading is taking place. Now if you go on and define one more ctor, may be because you want the object to be constructed in some other way, then you will have an overloaded ctor. In your case no overloading is taking place.
int getLineNumber() is just another member of the class.
2)
a: You are correct.
b: The parameters put inside "( )" are arguments list and if this function is called somewhere, then this list is type-matched and then function is called(in case of overloading). Now if you write a statement like:
Rectangle x(a, b, c, d);
then it means that your sc=a, lineNumber0=b, value1=c, value2=d for this function call.
In this below code, the foo function in the global scope tries to access the private variables of a Box, which ofcourse doesn't work. I have to make the foo function work with one line of code at the place show code for a school assignment.
#include <iostream>
using namespace std;
class Box {
int x,y;
public:
Box(int xi,int yi) {x=xi;y=yi;}
// One line of code to make foo(Box, Box) work
};
bool foo(Box l,Box r) {return (l.x*l.y)>(r.x*r.y);}
int main(int argc, char* argv[]) {
Box b1(3,4),b2(1,2);
if (foo(b1,b2)) cout << "b1>b2\n";
return cin.get();
}
Look into the friend keyword.
First off, this is not a priori a dirty thing. The placement of the comment line already indicates that the class Box controls who is allowed to touch its privates (pun intended).
Secondly, since this is a school assignment I think that the solution should have been mentioned in class: this can be achieved using a friend declaration.
Declare foo as a friend function inside Box
#include<iostream>
class Box {
int x,y;
public:
Box(int xi,int yi) :x(xi),y(yi){}// Always use initializer list for initializing data members, i.e. prefer initialization over assignment
friend bool foo(Box,Box);// friend functions can access private members
};
bool foo(Box l,Box r) // friend keyword not to be written while defining the function
{return (l.x*l.y)>(r.x*r.y);}
int main(int argc, char* argv[]) {
Box b1(3,4),b2(1,2);
if (foo(b1,b2)) std::cout << "b1>b2\n";
return std::cin.get();
}
In addition to the other answers involving friends, a better answer for the long term (although not a one-line change) would be for Box to overload the appropriate comparison operators.