structure and functions in C++ - c++

Can someone explain why this code gives the output 10? When I try to analyse it my logic gives as result 11.
#include <iostream>
using namespace std;
class A {
public:
A() { a.a = a.b = 1; }
struct { int a,b; } a;
int b(void);
};
int A::b(void) {
int x=a.a;
a.a=a.b;
a.b=x;
return x;
};
int main(void) {
A a;
a.a.a = 0;
a.b();
cout << a.b() << a.a.b << endl;
return 0;
}

In the cout line, a.b() could either be called before or after a.a.b is evaluated. Beginners sometimes assume left-to-right evaluation in this sort of code but actually that is not a rule of C++.
Those two different possibilities would explain your 10 and 11. To avoid ambiguity you could write:
cout << a.b();
cout << a.a.b << endl;
(assuming that order was your intent).
Note: C++17 may change this and define left-right evaluation order for this code.

Other than using a debugger, you can also use cout statements to help keep track of when things are called.
To kind of help myself out tracing your program I fixed a bit of the indentation and added comments as to when things are happening:
#include <iostream>
using namespace std;
class A {
public:
A() {
a.a = a.b = 1;
}
struct {
int a,b;
} a;
int b(void);
};
int A::b(void) {
cout << "Within A::b()" << endl;
// swap a.a, a.b
int x=a.a;
a.a=a.b;
a.b=x;
cout << "a.a.a = " << a.a << " a.a.b: " << a.b << endl;
return x;
};
int main(void) {
// sets a.a.a = 1, a.a.b = 1
A a;
// sets a.a.a = 0, a.a.b = 1
a.a.a = 0;
// a.a.a = 1, a.a.b = 0
a.b();
// check output here
cout << a.b() << a.a.b << endl;
return 0;
}
The above program results with the following output on http://cpp.sh/ :
Within A::b()
a.a.a = 1 a.a.b: 0
Within A::b()
a.a.a = 0 a.a.b: 1
10
In all, it depends on whether or not a.b() or a.a.b is resolved first when you call cout. In this case, operator precedence is undefined due to how cout works. This stackoverflow post has some good info on this.

Related

Parsing 2 Arrays to friend function

I am having troubles by accessing 2 of my arrays at the same time with my friend function.
Here is my code (the important part):
int main(){
// Array with fracture, example 3/4
cFracture cFArr[8] = {cFracture(3,4), cFracture(24,6)};
// One fracture have to be added to other
// I am missing something here ->
add(cFArr[0]);
return 0;
}
I need to understand, how to parse 2 Arrays at the same time.
Here is my add function, here is nothing in, i need to understand how to get 2 arrays at the same time...
int add(cFracture add_f){
cout << "Result after adding fracture 1 to fracture 2: " << add_f.a << "/" << add_f.b << endl;
return 0;
}
And here is my class:
cFracture{
int a;
int b;
public:
cFracture(int a_in = 0, int b_in = 0){
a = a_in;
b = b_in;
}
friend int add(cFracture add_f);
};
How should I go on? How to get 2 arrays at the same time, so i can add one to the other? It have to be done with friend function.
Just add another argument to the function.
int add(cFracture add_f1, cFracture add_f2){
cout << "Result after adding fracture 1 to fracture 2: " << add_f1.a + add_f2.a << "/" << add_f1.b + add_f2.b << endl;
return 0;
}
and change the friend declaration to match the new function.
cFracture{
int a;
int b;
public:
cFracture(int a_in = 0, int b_in = 0){
a = a_in;
b = b_in;
}
friend int add(cFracture, cFracture);
};
Then you can do:
add(cFarr[0], cfArr[1]);
in the main() function.

C++ inheritance with overloading not compiling?

I am making a Poker game in C++, and I am just trying to get started.
I need the ability to compare "Hands", to see which one is greater, equal, or lesser.
So, I have a Hand class now, and I made two other sub-classes that are called Straight and ThreeOfKind (I will add the rest later.
The Hand class has a method called compareTo(Hand* otherHand), it then checks the hand ranking to see which one is better. Also, with the Straights and Three of a Kinds, you can compare them together when they are of the same rank. Like Straights with Straights and Three of a Kinds with Three of a Kinds.
I wrote some initial code today, and my problem is, when I try to call "Hand's" compareTo(Hand* otherHand) method and pass in a Hand, Straight, or Three of a Kind, the compiler complains as it is trying to force me to use the Straight's compareTo(Straight* otherStraight) method. So, I should have overloading, but it's not working.
So in the Straight class after inheritance is done, we should have these two methods:
int Hand::compareTo(Hand* otherHand);
int Straight::compareTo(Straight* otherStraight);
// But, if you do this, it works:
Straight myStraight1 = new Straight(7);
Straight myStraight2 = new Straight(5);
myStraight1.compareTo(myStraight2);
// This is valid...
// If you do this, then the compiler complains!
Straight myStraight3 = new Straight(10);
ThreeOfKind myTrips4 = new ThreeOfKind(3);
myStraight3.compareTo(myTrips4);
// This above line complains that you cannot convert a ThreeOfKind to a Straight
// Even though I am trying to use Hand's compareTo(Hand* otherHand) method and
// cast a Three of a Kind to a Hand object,
// it fails with the overloading!
Here is all the source code...
//////////////////////////
// C++ main header file //
//////////////////////////
#pragma once
class Hand {
private:
int ranking;
public:
Hand(int aRanking);
Hand();
int getRanking();
int compareTo(Hand* otherHand);
};
class Straight : public Hand {
private:
int highCard;
public:
Straight(int aHighCard);
Straight();
int getHighCard();
int compareTo(Straight* otherStraight);
};
class ThreeOfKind : public Hand {
private:
int tripsValue;
public:
ThreeOfKind(int aTripsValue);
ThreeOfKind();
int getTripsValue();
int compareTo(ThreeOfKind* otherThreeOfKind);
};
///////////////////////////
// C++ main .cpp file... //
///////////////////////////
#include <iostream>
#include "PokerTest1.h"
using namespace std;
Hand::Hand(int aRanking) {
this->ranking = aRanking;
}
Hand::Hand() {
this->ranking = 0;
}
int Hand::getRanking() {
return this->ranking;
}
int Hand::compareTo(Hand* otherHand) {
cout << "COMPARING HANDS..." << endl;
if (this->getRanking() < otherHand->getRanking()) {
cout << "HANDS RETURNING -1..." << endl;
return -1;
}
else if (this->getRanking() > otherHand->getRanking()) {
cout << "HANDS RETURNING 1..." << endl;
return 1;
}
cout << "HAND RANKINGS ARE EQUAL..." << endl;
if (this->getRanking() == 4 && otherHand->getRanking() == 4) {
cout << "HANDS ARE BOTH STRAIGHTS..." << endl;
Straight* myStraight1 = (Straight*)this;
Straight* myStraight2 = (Straight*)otherHand;
cout << "COMPARING BOTH STRAIGHTS..." << endl;
return myStraight1->compareTo(myStraight2);
}
else if (this->getRanking() == 3 && otherHand->getRanking() == 3) {
cout << "HANDS ARE BOTH THREE OF A KINDS..." << endl;
ThreeOfKind* myTrips1 = (ThreeOfKind*)this;
ThreeOfKind* myTrips2 = (ThreeOfKind*)otherHand;
cout << "COMPARING BOTH TRIPS..." << endl;
return myTrips1->compareTo(myTrips2);
}
return 0;
}
Straight::Straight(int aHighCard) : Hand(4) {
this->highCard = aHighCard;
}
Straight::Straight() : Hand(4) {
this->highCard = 0;
}
int Straight::getHighCard() {
return this->highCard;
}
int Straight::compareTo(Straight* otherStraight) {
cout << "INSIDE STRAIGHT COMPARE TO..." << endl;
if (this->highCard < otherStraight->highCard) {
cout << "STRAIGHT COMPARE RETURNING -1..." << endl;
return -1;
}
else if (this->highCard > otherStraight->highCard) {
cout << "STRAIGHT COMPARE RETURNING 1..." << endl;
return 1;
}
cout << "STRAIGHT COMPARE RETURNING 0..." << endl;
return 0;
}
ThreeOfKind::ThreeOfKind(int aTripsValue) : Hand(3) {
this->tripsValue = aTripsValue;
}
ThreeOfKind::ThreeOfKind() : Hand(3) {
this->tripsValue = 0;
}
int ThreeOfKind::getTripsValue() {
return this->tripsValue;
}
int ThreeOfKind::compareTo(ThreeOfKind* otherThreeOfKind) {
cout << "INSIDE STRAIGHT COMPARE TO..." << endl;
if (this->tripsValue < otherThreeOfKind->tripsValue) {
cout << "TRIPS COMPARE RETURNING -1..." << endl;
return -1;
}
else if (this->tripsValue > otherThreeOfKind->tripsValue) {
cout << "TRIPS COMPARE RETURNING 1..." << endl;
return 1;
}
cout << "TRIPS COMPARE RETURNIN 0..." << endl;
return 0;
}
int main()
{
// Test the classes...
// with Straight compared to a Three of a Kind.
// Should try to invoke Hand::compareTo(Hand* otherHand) { ... };
// But, instead, it try to invoke Straight::compareTo(Straight* otherStraight) { ... };
// If you put both these methods in the Straight class (rather than using inheritence, it works)
// If you delete Straight::compareTo(Straight* otherStraight) { ... }, the line below compiles
// It is just strange why it won't compile...
Straight* myStraightA = new Straight(9); // Straight of 5, 6, 7, 8, 9
ThreeOfKind* myTripsB = new ThreeOfKind(2); // Three of a Kind of 2, 2, 2
cout << "Compare results..." << endl;
cout << myStraightA->compareTo(myTripsB) << endl; // Compiler error...
return 0;
}
Also, here is a list of the hand rankings:
0 → high card
1 → pair
2 → two pair
3 → three of a kind
4 → straight
5 → flush
6 → full house
7 → quads
8 → straight flush
9 → royal flush
Basically I have a field in the Hand class that stores these rankings as integers. Just so you know.
Lastly, this is the compiler error message:
error C2664: 'int Straight::compareTo(Straight )': cannot convert argument 1 from 'ThreeOfKind' to 'Straight*'
You are trying to overload across classes.
The compiler looks for a compareTo method, finds it in Straight, and doesn't look at Hand. If you add an appropriate using statement, you can tell it to look at Hand's compareTo as well to accomplish your overloading.
class Straight : public Hand {
private:
int highCard;
public:
using Hand::compareTo; // <<< HERE
Straight(int aHighCard);
Straight();
int getHighCard();
int compareTo(Straight* otherStraight);
};
Instead of doing this, I'd recommend you use getRanking() for comparison between hands of different hand types, and define getTieBreaker() overridden by subclasses to handle cases of the same type of hand.
class Hand {
public:
int getRanking();
// virtual causes subclass' version to be called if done from reference or pointer.
virtual int getTieBreaker();
};
This simplifies how Hand compares:
int Hand::compareTo(Hand* otherHand) {
if (this->getRanking() < otherHand->getRanking()) {
return -1;
}
else if (this->getRanking() > otherHand->getRanking()) {
return 1;
}
if (this->getTieBreaker() < otherHand->getTieBreaker()) {
return -1;
}
else if (this->getTieBreaker() > otherHand->getTieBreaker()) {
return 1;
}
return 0;
}
And lets you define it in Straight:
class Straight : public Hand {
//...
public:
int getHighCard();
int getTieBreaker();
};
int Straight::getTieBreaker() {
return this->highCard;
}

references in c++ with static

Below is a output question.I am not able to understand why its answer is 30.
#include<iostream>
using namespace std; //namespace std is being used
int &fun()
{
static int x = 10; //x is static
return x;
}
int main()
{
fun() = 30;
cout << fun(); //fun() called
return 0;
}
OUTPUT:30
Can anybody tell why output is coming to be 30 and also can explain the role of static keyword
In computer programming, a static variable is a variable that has been allocated statically—whose lifetime or "extent" extends across the entire run of the program
void foo()
{
int a = 10;
static int b = 10;
a++;
b++;
std::cout << "a : " << a << " , b : " << b << std::endl;
}
A reference variable is an alias, that is, another name for an already existing variable. Once a reference is initialized with a variable, either the variable name or the reference name may be used to refer to the variable.
int a = 4;
int b = a;
int &c = a;
c++;
std::cout << "b = " << b << std::endl; //4
std::cout << "a = " << a << std::endl; //5
std::cout << "c = " << c << std::endl; //5
/* Becaues c is a refence to a, it means that
a and c are just different names to the same memory location
so updating either one updates the actual value in memory
*/
a++;
std::cout << "c = " << c << std::endl; //6
std::cout << "a = " << a << std::endl; //6
//consider the function below:
int &bar()
{
static int a = 5;
std::cout << "a is " << a << std::endl;
return a;
}
Testing the two:
int main()
{
for (int i = 0; i < 3; i++)
foo();
//for every call of foo():
//memory allocation for a is created and deleted when a goes out of scope
//memoery allocation for b extends through out the life of the program
//bar() returns a reference to "a" i.e
int reference_to_a = bar(); //prints 5
reference_to_a = 30;
bar(); //prints 30
bar() = 50; //prints 30 and later assigns 50 to the reference returned.
bar(); //prints 50
}
static make the variable persist across function calls.
which means static int x = 10; will be executed once when func is called for the first time.
int static_test()
{
static int x = 10;
x++;
return x;
}
static_test(); // first call will return 11
static_test(); // second call will return 12 because the value of x ( was saved and was then incremented)
static_test(); // third call will return 13
Now, you need to understand what reference are. To understand what reference are you need to understand pointers. I am guessing you will easily find some website explaining those two.
case 1:
#include<iostream>
using namespace std; //namespace std is being used
int &fun()
{
int x = 10; //x is static
return x;
}
int main()
{
fun() = 30;
cout << fun(); //fun() called
return 0;
}
Here, in the call fun(), we are declaring a local variable int x, which goes out of scope once it returns from fun().
so, in the line cout << fun() a new variable is declared and address of the new variable is returned.
case 2:
static int x = 10;
here, since variable 'x' is static, it can be initialized only once. i.e., the first time x is initialized to 5 and then over written to 30.
now when you are making the function call subsequent times, static int x = 5 is ignored. Hence, it returns the value 30

Why this data member is initialized? [duplicate]

This question already has answers here:
Uninitialized values being initialized?
(7 answers)
Closed 8 years ago.
I'm doing some testing...
Firstly I post my source code
the .h file
class Complex{
private:
int r = 0;//initializer
int i ;
public:
Complex(int , int I = 0);
Complex();
void print();
void set(int, int I = 1);
static void print_count();
static int count;
};
the .cpp file
#include <iostream>
#include "complex.h"
int Complex::count = 1;
Complex::Complex(int R , int I){
r = R;
i = I;
count++;
std::cout << "constructing Complex object...count is " << Complex::count << std::endl;
}
Complex::Complex(){//default constructor
std::cout << "default constructor is called..." << std::endl;
}
void Complex::print(){
std::cout << "r = " << r << ';' << "i = " << i << std::endl;
return;
}
void Complex::set(int R, int I /*= 2*/){//will be "redefaulting", an error
r = R;
i = I;
return;
}
void Complex::print_count(){//static
Complex::count = -1;//jsut for signaling...
std::cout << "count is " << count << std::endl;
return;
}
the main function
#include <iostream>
#include "complex.h"
int main(){
Complex d;//using default constructor
d.print();
/*Complex c(4, 5);*/
Complex c(4);
//c.print();
/*c.set(2, 3)*/
c.print();
c.set(2 );
c.print();
std::cout << "count is " << c.count << std::endl;//c can access member data
c.print_count();
c.count++;//
return 0;
}
consider the Complex object d constructed with default ctor
because the data member r is initialized using with 0, when executing d.print(),
r is expected to be 0
and i isn't, so I expected it to be garbage value
but when I'm testing, one strange thing happens.
if I eliminate this and the following lines of code in the main file:
std::cout << "count is " << c.count << std::endl;//c can access member data
then d.print() will give the value of i as 32767 on my system, which I guess it's a garbage value;
but once that line is added, d.print() just give i's value to 0 on my system.
I don't get it. I hasn't set, modiify or initialize i's value, why should it be 0?
or, it is also a garbage value?
or, calling one of those function corrupts the value of i?
how is the thing run behind the scene here?
thx for helping.
0 is just as garbage value as any other. Don't make the mistake of thinking otherwise.
Formally, reading an uninitialized variable is undefined behavior, so there's no point in wondering about it: just fix it by initializing the variable properly.

Dereferencing pointers to members of union

The following code prints '2' four times. Why does it never print '1'? Can someone explain me exactly what is happening here?
#include <iostream>
int main () {
union IntegersUnion {
int a;
int b;
};
IntegersUnion q;
q.a = 1;
q.b = 2;
std::cout << "(*(&q.a)) = " << (*(&q.a)) << std::endl;
std::cout << "(*(&q.b)) = " << (*(&q.b)) << std::endl;
std::cout << "(*(&(q.a))) = " << (*(&(q.a))) << std::endl;
std::cout << "(*(&(q.b))) = " << (*(&(q.b))) << std::endl;
return 0;
}
A union shares the memory between its members. By doing:
q.a = 1;
q.b = 2;
the second assignment overwrites the a.
union uses the same memory for all of its members.
So, when you assign q.b = 2;, q.a will be 2, too.
Every item in the union refers to the same location.
The most common use of union is something like this:
struct {
int dataTypeID;
union {
char char_here;
int number_here;
}
} incoming_data;
In this example, incoming_data is data imported from a file, where dataTypeID tells you what kind of data it is. (There are many file formats which optimize space in this fashion.)