Here's a program, where I am trying to call the class constructor multi::multi(int, int), in the function void multi::multiply(). The output is
30
30
instead of expected
30
25
Why?
#include <iostream.h>
class multi{
private:
int a;
int b;
public:
multi(int m, int n){
a = m;
b = n;
}
void multiply(){
cout << "\n\n" << a*b;
multi (5, 5);
cout << "\n" << a*b;
}
};
main(){
multi x(5,6);
x.multiply();
return 0;
}
multi (5, 5);
It creates a temporary object, and gets destroyed by the end of the full expression. It doesn't do multiplication or printing.
To see the desired output, you can add a reset() member function to your class:
class multi{
private:
int a;
int b;
public:
multi(int m, int n) : a(m), b(n) {} //rewrote it
void reset(int m, int n) { a = m; b = n; } //added by me
void multiply(){
cout << "\n\n" << a*b;
reset(5, 5); //<-------------- note this
cout << "\n" << a*b;
}
};
By the way, prefer using member-initialization-list when defining constructors.
When you're calling the constructor multi(5, 5) you're actually creating a temporary object that is immediately destructed.
This doesn't work, because multi(5, 5); creates a temporary object of class multi, which is immediately destroyed, because it is not used for anything
Since multiply() is a member function of class multi, it has access to the private members, so it can just set a and b directly. You can get your expected output by rewriting multiply like this:
void multiply()
{
cout << "\n\n" << a*b;
b = 5;
cout << "\n" << a*b;
}
You can't call constructors like this. What your code does is create a new temporary instance of multi, which gets discarded immediately.
Once an object is constructed, you can't call its constructor again. Create an assign() function or something similar in your class.
You can't call a constructor of an already created object. What you are doing in code is, creating a temporary object.
Compiler will report error if you do try to do
this->multi(5,5).
Related
#include <iostream>
using namespace std;
void b();
int main() {
int a = 10;
b();
}
void b() {
int a;
cout<<"Int a="<<a;
}
I am looking to print the value of a in the main scope using a function, with my current code, it prints Int a=0. How can I achieve this?
Don't declare an entirely new a inside b().
Pass the a from main to b() and then print that.
For example:
#include <iostream>
void b(int whatever_name_you_want_here);
int main()
{
int a = 10;
b(a);
}
void b(int whatever_name_you_want_here)
{
std::cout << "Int a=" << whatever_name_you_want_here;
}
//Change your code to the following and it will give you the result you're looking for.
On your code there is no way to pass int a on the main to b(); unless b accepts a parameter of the type you want the function to output.
#include<iostream>
void b(int);
int main()
{
int a = 10;
b(a);
}
void b(int a){
std::cout << "int a=" << a;
}
I guess the main problem is not being aware of something very important which is called scope! Scopes are usually opened by { and closed by }
unless you create a global variable, it is only known inside the scope it has been introduced (declared).
you declared the function b in global scope :
void b();
so after this every other function including main is aware of it and can use it.
but you declared the variable a inside the scope of main:
int a = 5;
so only main knows it and can use it.
Please make note that unlike some other programming languages, names are not unique and not every part of the program recognize them in c and c++.
So the part:
void b() {
int a;
does not force the function b to recognize the a which was declared in main function and it is a new a.
so to correct this mistake simply give the value or reference of variable a to function b :
#include <iostream>
void b(int&);
int main() {
int a = 10;
b(a);
}
void b(int& a) {
std::cout << "Int a=" << a << std::endl;
}
please also note that the a as argument of the function b is not the same a in the function main.
The final tip is every argument for functions is known inside that function scope as it was declared inside the function scope!
What you want to achieve requires you to pass a value to a function. Let me give you an example on how to do that.
#include<iostream>
void print_value(int value){
std::cout << "Value is: " << value << '\n';
}
int main(){
int a = 5;
print_value(a);
return 0;
}
The only thing you are missing in your program is the parameter. I won't bother explaining the whole thing over here as there are numerous articles online. Here is a straightforward one.
Refer to this to understand how functions work in C++
Use pass by reference to access a variable which is declared in one function in another.
Refer the below code to understand the use of reference variable,
void swapNums(int &x, int &y) {
int z = x;
x = y;
y = z;
}
int main() {
int firstNum = 10;
int secondNum = 20;
cout << "Before swap: " << "\n";
cout << firstNum << secondNum << "\n";
// Call the function, which will change the values of firstNum and secondNum
swapNums(firstNum, secondNum);
cout << "After swap: " << "\n";
cout << firstNum << secondNum << "\n";
return 0;
}
#include <iostream>
using namespace std;
void displayValue(int number) {
cout<<"Number is = "<<number;
}
int main()
{
int myValue = 77;
displayValue(myValue);
return 0;
}
I have two functions that do the same thing: they add two numbers. One adds two numbers which are members of the class, the other adds numbers given by the user, outside the class.
Is there any way to write one single function that adds two numbers and checks whether the arguments are user input or class members?
void myclass::add(){
cout<<this->a+this->b;
}
void myclass::add(int a,int b){
cout<<a+b;
}
While you cannot really do it in a single function the common approach would be to write the more flexible of the two and use the other one just as a dispatcher:
void myclass::add(int a, int b) {
std::cout << (a+b);
}
void myclass::add() {
add(a,b);
}
Now, there are a different number of smells in this code... a function name reused to act on members or only inputs is one (a function that does not touch the object's state already smells at it not being a member, or being a static one). Printing inside a function called add (should it not return the values?)...
Disclaimer : I don't encourage such coding.
Ok, here's a method
void myClass::Add(int& a, int& b)
{
if (&a==&this->a)
{
std::cout << this->a + this->b
} else {
std::cout << a+b;
}
}
Ofc , things like myClass->Add(10,4) won't work... you will need some stack variables to hold the 10 and 4 variables.
So you want a single function that can have two different parameters? It isn't possible.
void myclass::add(int a, int b)
{
cout << a + b << endl;
}
Is what you want; but you can overload the function:
void myclass::add()
{
cout << memberA + memberB << endl;
}
In my opinion, this is a much better solution than having a single function that checks whether the variables are members or not; it makes your code readable. Don't be afraid to overload functions - it's one of those things that makes C++ awesome. I've created a class to demonstrate this:
class myClass
{
public:
myClass() : memberA(0), memberB(0) {}
~myClass() {}
void setNumbers(int a, int b)
{
memberA = a;
memberB = b;
}
void add(int a, int b)
{
cout << a + b << endl;
}
void add()
{
cout << memberA + memberB << endl;
}
private:
int memberA;
int memberB;
};
int main()
{
myClass m;
m.setNumbers(1, 2);
m.add();
return 0;
}
I've tested the add function with and without parameters and they both output the same result. The former because I used a setNumbers(..) function. Effectively, your first scenario of having two functions is the most apt solution to begin with.
In you realy wanted a single function, the way to do it is with optional default parameters.
Your declaration will be
void add(optional<int> a = optional<int>(), optional<int> b = optional<int>() );
Then in your implementation:
a ? a.get() : this->a
A benefit of this approach is that you can mix members and parameters. For example:
obj.add(1);
obj.add(optional<int>(), 2);
I am trying to learn C++ and from what I've read in books and on SO:
If I use auto x = new Object(); x is a pointer to address of Object and this is in dynamic memory and exists until I delete it.
However if I use Object x; or auto x = Object() it only lasts until it goes out of scope.
In an example they have shown this:
void foo()
{
Point p = Point(0,0);
} // p is now destroyed.
What I don't understand is what happens when I return a object when I don't use new? Will it be a copy of the object?
Here is an example of what I am not sure about:
class Object
{
public:
int X;
static Object Foo(int y)
{
Object result;
result.X = y;
return result;
}
};
class TestContainer
{
public:
void Run()
{
for(auto i = 0; i < 10; i++)
{
_objects.at(i) = Object::Foo(i + (rand() % 10 + 1));
}
}
private:
std::vector<Object> _objects;
};
void main()
{
TestContainer tc;
while(true)
{
tc.Run();
}
}
Note I haven't tested this code but I think it illiterates my confusion. In my main function I instantiate TestContainer and endless call it's Run method. This in turn loops calling a static Foo method on Object that returns a copy of a new Object, which is stored in a vector.
My question is, what happens with all the Object's? If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?
Will it be a copy of the object?
Yes.
Or a move could be used instead, or the entire thing could be optimised away to produce only one actual object in your final, compiled program.
But, basically, yes.
If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?
Yes.
As an aside, you're using at on elements that don't exist; to add elements, use insert or push_back.
A simple class like this behaves much like a POD variable. o1=o2 copies the fields, element-wise. So the target Object of an assignment does not get deleted but overwritten.
Objects which go out of scope "go away" (because the stack is unwound) like e.g. an int.
Here is a run-able example that I believe illustrates this behavior:
#include <iostream>
using namespace std;
class Foo {
private:
int id;
public:
Foo(int x)
: id(x)
{
cout << this->id << " is created" << endl;
}
Foo(const Foo& rhs)
: id(rhs.id)
{
cout << "copied " << this->id << endl;
}
Foo& operator=(Foo rhs){
this->id=rhs.id;
cout << "assigned " << this->id << endl;
return *this;
}
~Foo(){
cout << this->id << " is destroyed" << endl;
}
int getID(){
return this->id;
}
};
Foo bar(){
Foo f1 = Foo(1);
cout << f1.getID() << " from bar" << endl;
return f1;
}
int main(){
Foo f2 = bar();
cout << f2.getID() << " from main" << endl;
return 0;
}
This produces this output:
1 is created
1 from bar
1 from main
1 is destroyed
From this, I'm not seeing a copy or an assignment. I suspect what is happening is that both f1 and f2 are referencing the same instance of the object in memory. The object is not being de-allocated when the f1 reference goes out of scope because the object has another reference assigned to it.
I tried asking before but I wasn't very clear so I'm re-asking it.
I want to have a variable that depends on the value of another variable, like b in this example:
int main(){
int a;
dependent int b=a+1; //I'm just making this up
a=3;
cout << b; //prints 4
a=4;
cout << b; //prints 5
}
Of course, this does not exist in C++, but this is what I want.
So instead I tried making a function:
int main(){
int a;
int b(){ return a+1; } //error
a=3;
cout << b(); //would print 4 if C++ allowed nested functions
a=4;
cout << b(); //would print 5 if C++ allowed nested functions
}
The above doesn't work because C++ doesn't allow nested functions.
I can only make functions outside of main(), like this:
int b(){
return a+1; //doesn't work because a is not in scope
}
int main(){
int a;
a=3;
cout << b();
a=4;
cout << b();
}
But this does not work because a is not in the same scope as b(), so I would have to pass a as a parameter and I don't want to do that.
Are there any tricks to get something similar to a dependent variable working in C++?
What you need is a closure. If you can use C++ 0x features, you are in luck. Otherwise, you can define one manually:
#include <iostream>
using namespace std;
struct B
{
const int & a;
B(const int & a) : a(a) {}
// variable syntax (Sean Farell's idea)
operator int () const { return a + 1; }
// function syntax
int operator () () const { return a + 1; }
};
int main()
{
int a;
B b(a);
a = 3;
cout << b << '\n'; // variable syntax
a = 4;
cout << b() << '\n'; // function syntax
}
You can also define B inside main, but some compilers would not like it.
The C++ 0x lambda syntax looks like this:
auto b = [&]() { return a + 1; }
The [&] means that the lambda captures local variables by reference.
If you're using C++0x (GCC 4.5+, Visual C++ 2010), you can use lambdas:
int a = 5;
auto b = [&a]{ return a + 1; };
std::cout << b() << std::endl;
Depending on what you're doing, though, there are probably cleaner solutions - possibly some variation of the classic "method that takes in 'a' and returns 'b'"
You could define a class that had a member a, and then a function b() that returned the value of a+1. A basic implementation would be something like:
class Dependent {
public:
Dependent(void) { m_value = 0; }
void set(int value) { m_value = value; }
int b(void) { return(m_value + 1); }
private:
int m_value;
};
int main(){
Dependent a;
a.set(3);
cout << a.b();
a.set(4);
cout << a.b();
}
You could add operator overloading as appropriate to make it work more like normal integers if you so desired.
This is possible if you use lambda functions (c++0x), because they can capture local variables.
Example:
int main()
{
int a;
auto f = [&] () -> int { return a + 1; };
a = 3;
std::cout << f() << std::endl;
a = 4;
std::cout << f() << std::endl;
return 0;
}
Result:
4
5
(See http://ideone.com/MlzX7 for proof)
A simple approach is to use pre-processor macros, nothing C++ specific about it though:
#define b ((a)+1)
int main(){
int a;
a=3;
cout << b;
a=4;
cout << b;
}
#undef b
Are you OK using C++0x ? if yes,
int main()
{
int a = 10;
auto b = [&a]() -> int { return a + 1; };
cout << b() << endl;
}
Since, it is not tagged with c++0x, you can use nested classes instead of nested functions. This column from Herb sutter would help you for existing c++. http://www.gotw.ca/gotw/058.htm
The above doesn't work because C++ doesn't allow nested functions.
You can simulate that using nested structure. In C++0x you can make use of lambda function, which provides the same means of function inside function.
Define a class called LinkedInt or something that behaves like an int, but has a RelatedTo relationship on itself and an additional member that is a function pointer to the function to evaluate when computing the integer's value. Pretty straightforward. Let me know if you need some pointers on the coding.
The short answer is that OOP is more than enough to bury this problem.
I want to have a variable that depends on the value of another
variable, like b in this example:
I see you just need a reference variable:
int a;
int &b =a;
a=10;
cout << b; // 10
Why C++0x lambdas do come for this, I dont understand.
using namespace std;
class A {
public:
A() {}
~A() {}
map<int, string*>& getMap() {
return mapStr;
}
void setMap(const map<int,string*> m) {
mapStr = m;
}
private:
map <int, string*> mapStr;
};
class B {
public:
A getA() {
return a;
}
private:
A a;
};
int main(int argc, char*argv[]) {
map<int, string*> mm;
mm.insert(std::make_pair(1, new string("abc")));
mm.insert(std::make_pair(2, new string("def")));
B b;
b.getA().setMap(mm);
cout << "Size " << b.getA().getMap().size() << std::endl;
return 0;
}
Output:
Size 0
Any ideas as to why does this return the map size to be 0 and what needs to be done to be fixed
Your getA method is returning a temporary copy of a, so your call to setMap is modifying that copy, not the original. One way to fix this would be to have getA return a reference or pointer to a
You're returning a copy of an A, not the A object you're modifying. Try out this code to understand the difference:
int main (int argc, char* argv[])
{
map<int, string*> mm;
mm.insert(std::make_pair(1, new string("abc")));
mm.insert(std::make_pair(2, new string("def")));
B b;
A a = b.getA();
B bb;
bb.getA().setMap(mm);
a.setMap(mm);
cout << "A Size " << a.getMap().size() << std::endl;
cout << "BA Size " << bb.getA().getMap().size() << std::endl;
}
B::getA() is returning an object by value. Si when you call A::setMap() you are setting the map of the temporary object.
Change the signature of getA() to:
A &getA();
Your method getA currently returns a copy, instead of a reference to, the a member. Instead, you want to return A& from getA. This will allow you to return a reference to your member variable instead of a copy of it.
Each call to getA() is creating and returning a new temporary object.
So the first call:
b.getA().setMap(mm);
Creates an A object adds mm into it.
This then goes out of scope and destroys the map.
This line:
cout << "Size " << b.getA().getMap().size() << std::endl;
Creates a completely new A object with its own empty map.
As it is a new object the size of the map is zero.
Once this goes out of scope it is again destroyed.
I think what you meant to do is:
class B
{
A& getA() // Notice the & just after the A
{ // rather than return an object by value
return a; // you want to return a reference to the object inside
} // your B object.
private:
A a;
}