I have an object of class A.
class A[
{
int x;
string y;
float z;
....
}
Then I have an int, called "integer".
How can I redefine the = operator in order to do something like
int integer;
A obj = integer;
in order to obtain something equal to the constructor call with NOT all members:
A obj(integer,",0);
This is a little naughty, but:
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
int x;
A & operator=(int value) {
x = value;
return *this;
}
};
int main(int, char **) {
A obj;
obj.x = 5;
cout << "Initially: " << obj.x << endl;
obj = 10;
cout << "After: " << obj.x << endl;
}
When run:
g++ Foo.cpp -o Foo && Foo
Initially: 5
After: 10
Is this what you're trying to do? Note that this is very naughty. class A is NOT an integer, and assigning it to an int is going to confuse people. C++ lets you do things that you probably shouldn't do, and this is one of them.
Related
It's a long time ago since my last c++ project and now I'm stuck in a very simple problem. I create two objects and want to modify only one of them. Now I don't understand why the other object is also modified...
MainClass:
#include "testobject.h"
#include <iostream>
int main() {
TestObject o1;
TestObject o2;
std::cout << "object1 before: " << o1.getI() << std::endl;
std::cout << "object2 before: " << o2.getI() << std::endl;
o1.setI(2);
std::cout << "object1 after: " << o1.getI() << std::endl;
std::cout << "object2 after: " << o2.getI() << std::endl;
}
TestObjectClass:
#include "testobject.h"
int i;
int TestObject::getI() {
return i;
}
void TestObject::setI(int j) {
i = j;
}
The output is:
object1 before: 0
object2 before: 0
object1 after: 2
object2 after: 2
Why is i in object2 also set to 2?
The both objects refer to the common variable
int i;
declared in the global namespace. So once the variable is changed the class method
int TestObject::getI() {
return i;
}
will return the same value of the variable i for both objects.
Make the variable a data member of the class.
For example
class TestObject
{
//...
private:
int i;
};
Pay attention to that the member function getI should be declared with the qualifier const because it does not change the object itself
class TestObject
{
public:
int getI() const {
return i;
}
//...
};
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
I have been attempting to create a function getLocation() that utilizes a pointer to return the value of the struct Location declared in the Character class. I was curious as to the problem with my syntax (or my structure). Knowing that the asterisk * should refer to the value, why is it that my function using an ampersand string& Character::getInventory is able to return the value of that particular index (its return does not need to be converted)?
Trying Location& Character::getLocation() {return position; }
when run results in error C2679: binary '<<': no operator found
Nor
Location*
Which cannot be run as there is no conversion.
I read that the following is likely the most proper because it specifies the scope in which the structure resides, but still results in needing and returning a temporary.
Character::Location* const & Character::getLocation() {return &position; }
Any advice or input would be greatly appreciated, thanks in advance.
Below is my main.cpp, which of course will show the hexadecimal address for Location.
#include <iostream>
#include <string>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::string;
class Character {
private:
string name;
string inventory[4];
public:
struct Location {
int x; int y;
};
Location position;
public:
void Character::setName(string x) { name = x; }
string Character::getName() { return name; }
void Character::setLocation(int x, int y) {
position.x = x; position.y = y;
}
Location* Character::getLocation() {return &position; }
void Character::setInventory(string(&x)[4]) { for (int i = 0; i < 4; ++i) { inventory[i] = x[i]; } }
string& Character::getInventory(int itemNumber) { return inventory[itemNumber]; }
};
void showUser(Character Character);
int main() {
try {
string items[4] = { "Sword", "Shield", "Potion", "Cloak" };
Character CharacterI;
CharacterI.setName("Some Character");
CharacterI.setInventory(items);
CharacterI.setLocation(1, 30);
cout << "\n" << "Retrieving Character Info..." << "\n" << endl;
showUser(CharacterI);
}
catch (std::exception & e) {
cerr << "\nError : " << e.what() << '\n';
}
system("pause");
return 0;
}
void showUser(Character character) {
cout << "Name : " << character.getName() << endl;
cout << "Location : " << character.getLocation() << endl;
for (int i = 0; i < 4; ++i) {
cout << "Inventory " << i + 1 << " : " << character.getInventory(i) << endl;
}
}
Ok, I think I understand the question better now. The reason why getInventory can successfully return a reference while getLocation does not is because getLocation returns a reference to a temporary variable, which is not good. See the link in #NathanOliver's comment for details. Additionally, to paraphrase a previous comment by #Peter Schneider, an * in an expression dereferences a pointer to return a value, while in a declaration it signifies that a variable will be of pointer type. The two usages are more or less opposites of each other. Example:
int* p = new int; //Declares a pointer to int
int x = *p; //Dereferences a pointer and returns an int
What you need to do is create a member variable to hold the Character's location, then set/get from that variable instead of creating temporaries. You did this already for name and inventory, just keep using that same pattern.
Additionally, whenever you use the Location struct outside of the Character class scope, you need to fully-qualify it with Character::Location.
Example:
#include <iostream>
using namespace std;
class Character {
public:
struct Location {
int x;
int y;
};
Location loc;
void SetLocation(int x, int y) {loc.x = x; loc.y = y;}
Location& GetLocation() {return loc;}
};
int main ()
{
Character c;
c.SetLocation(1,42);
Character::Location l = c.GetLocation();
cout << l.x << endl << l.y << endl;
return 0;
}
Output:
1
42
I'm new to C++ and could not figure out how can I define a variable that holds 3 values,
e.g. coordinates hold 2 values, as (x,y).
I tried:
typedef int U_K(int a,int b,int c);
but that doesn't seem to work.
I'd really appreciate a quick simple answer :)
Thanks!
edit:
So i did this :
struct U_K{
float a,b,c;
};
U_K Uk; //this line
is this wrong? because i get "unknown type name U_K" for that line... i first though its because i needed to declare it under the function i am going to use the struct for, but turns out there is the error for both cases.
the shortest way is to use a struct
struct U_K
{
int a,b,c;
};
usage:
U_K tmp;
tmp.a = 0;
tmp.b = 1;
tmp.c = 2;
You can add complexity to that type by adding member function/constructors to make the usage of U_K easier:
struct U_K
{
int a,b,c;
U_K() //default constructor
:a(0)
,b(0)
,c(0)
{}
U_K(int _a_value,int _b_value, int _c_value) //constructor with custom values
:a(_a_value)
,b(_b_value)
,c(_c_value)
{}
};
//usage:
int main()
{
U_K tmp(0,1,2);
std::cout << "a = " << tmp.a << std::endl;//print a
std::cout << "b = " << tmp.b << std::endl;//print b
std::cout << "c = " << tmp.c << std::endl;//print c
}
Alternatively you can use std::tuple to obtain the same result. Using it is different:
std::tuple<int,int,int> t = std::make_tuple(0,1,2);
std::cout << "a = " << std::get<0>(t) << std::endl;//print first member
std::cout << "b = " << std::get<1>(t) << std::endl;//print second member
std::cout << "c = " << std::get<2>(t) << std::endl;//print third member
If you are learning c++ now you should know that the implementation std::tuple is much more complex than a trivial struct and to understand it you need to learn about templates and variadic templates.
struct TypeWith3Ints
{
public:
int a;
int b;
int c;
};
Use std::array<int, 3> which is to be preferred over tuple in this case as a homogenous container can be used.
If you want to typedef:
#include <array>
typedef std::array<int, 3> X;
Use std::tuple, then you don't have to make your own structure. Just write
std::tuple<int, int, int> your_tuple(a,b,c);
std::cout << std::get<1>(your_tuple) << ' '; // b
your_tuple = std::make_tuple(c,d,e);
std::cout << std::get<0>(your_tuple) << ' '; // c
If you want your own name, use alias, like:
typedef std::tuple<int, int, int> your_name;
your_name your_object(a,b,c); //your_tuple
std::cout << std::get<2>(your_tuple) << ' '; // c
If you want, your own structure, and if you want to write object(x,y,z), than you should make constructor or even overload operator (). It's more complicated. I suggest not to do it. Unless that has a deeper meaning. If you really want it, it could look like:
struct coordinate
{
int x,y,z;
coordinate(int a, int b, int c) : x(a), y(b), z(c)
{}
void operator()(int a, int b, int c)
{
x = a;
y = b;
z = c;
}
} my_object(10,20,30);
int main()
{
std::cout<<my_object.x<<' '<<my_object.y<<' '<<my_object.z<<'\n';
my_object(30,40,50);
std::cout<<my_object.x<<' '<<my_object.y<<' '<<my_object.z<<'\n';
return 0;
}
You can also do not make constructor and use {} notation.
I defined struct in the global scope, but when I try to use it, I get error: ‘co’ does not name a type, but when I do the same in a function, everything works fine
typedef struct {
int x;
int y;
char t;
} MyStruct;
MyStruct co;
co.x = 1;
co.y = 2;
co.t = 'a'; //compile error
void f() {
MyStruct co;
co.x = 1;
co.y = 2;
co.t = 'a';
cout << co.x << '\t' << co.y << '\t' << co.t << endl;
} //everything appears to work fine, no compile errors
Am I doing something wrong, or structures just cannot be used in global scope?
It's not that you "can't use structures in global scope". There is nothing special here about structures.
You simply cannot write procedural code such as assignments outside of a function body. This is the case with any object:
int x = 0;
x = 5; // ERROR!
int main() {}
Also, that backwards typedef nonsense is so last century (and not required in C++).
If you're trying to initialise your object, do this:
#include <iostream>
struct MyStruct
{
int x;
int y;
char t;
};
MyStruct co = { 1, 2, 'a' };
int main()
{
std::cout << co.x << '\t' << co.y << '\t' << co.t << std::endl;
}
Structure can be "used" as in "you can create a global variable of it".
The remainder of code, co.x = 1; and the rest can appear only inside functions.
I'm learning about struct types in C++ and I tried to write a function that would change the values of the members of a struct type variable.
However, it produces an unexpected output and I can't figure out why this is happening.
/Program to test struct types/
#include <iostream>
#include <cstring>
using namespace std;
struct myStruct
{
string a;
string b;
int c;
float d;
};
void assignValues(myStruct myobj)
{
myobj.a = "foobar";
myobj.b = "Foo Bar";
myobj.c = 12;
myobj.d = 15.223;
}
int main()
{
myStruct x;
cout << x.a <<endl;
//x.a = "Hello world";
//x.b = "This is C++";
//x.c = 10;
//x.d = 13.1332;
assignValues(x);
cout << x.a<<endl;
cout << x.b << endl;
cout << x.c << endl;
cout << x.d << endl;
}
If I use the individual assignment statements, (that I have commented out in the code) instead of the assignValues() function, I get the expected output.
PS: The values I expected for the output are as follows:
foobar,
Foo Bar,
12,
15.223
Pass myStruct argument by reference to assignValue function, so it can be modified:
void assignValues(myStruct& myobj)
^^^ pass by reference
{
myobj.a = "foobar";
myobj.b = "Foo Bar";
myobj.c = 12;
myobj.d = 15.223;
}
Although you can pass a pointer to function:
void assignValues(myStruct* myobj) //<---- pointer
{
myobj->a = "foobar";
myobj->b = "Foo Bar";
myobj->c = 12;
myobj->d = 15.223;
}