Initialize member variables with multiple constructor calls - c++

I'm trying to execute the following code:
#include <iostream>
using namespace std;
class ABC {
private:
int x, y;
public:
ABC(){
cout << "Default constructor called!" << endl;
ABC(2, 3);
cout << x << " " << y << endl;
}
ABC(int i, int j){
cout << "Parameterized constructor called with parameters "<< i << " " << j << "!" << endl;
x = i;
y = j;
cout << x << " " << y << endl;
}
};
int main(){
ABC a;
return 0;
}
I am getting the following output:
Default constructor called!
Parameterized constructor called with parameters 2 3!
2 3
-858993460 -858993460
Shouldn't the member variables be initialized with values 2 and 3?

ABC(2, 3); doesn't call the constructor to initialize the members, it just create a temporary variable which will be destroyed immediately.
If you meant delegating constructor you should:
ABC() : ABC(2, 3) {
cout << "Default constructor called!" << endl;
cout << x << " " << y << endl;
}
Note this is a C++11 feature. You can add a member function if you can't use C++11.
class ABC {
private:
int x, y;
init(int i, int j) {
x = i;
y = j;
}
public:
ABC(){
cout << "Default constructor called!" << endl;
init(2, 3);
cout << x << " " << y << endl;
}
ABC(int i, int j){
cout << "Parameterized constructor called with parameters "<< i << " " << j << "!" << endl;
init(i, j);
cout << x << " " << y << endl;
}
};

You create a temporary variable in ABC() body. You can use this syntax to overcome this:
class ABC
{
private:
int x, y;
public:
ABC() : ABC(2,3)
{
std::cout << "Default constructor called!" << std::endl;
}
ABC(int i, int j)
{
std::cout << "Parameterized constructor called with parameters "<< i << " " << j << "!" << std::endl;
x = i;
y = j;
std::cout << x << " " << y << std::endl;
}
};

Related

std::move triggered destructor?

I'm adapting to an interface with parameter const vector<pair<int32_t, A>>& as.
To avoid multi-construct and multi-destruct, I write CreateAs as follow.
I was expecting it to trigger create move del each for once, but it turned out triggered move and del for twice.
What's the reason?
I made this way so that the A objects could destroy themselves automatically, even with new but without delete. Am I doing it right?
To reproduce it: https://repl.it/#unix1/ShrillFirsthandAdvance
#include <iostream>
#include <vector>
using namespace std;
struct A {
A() { cout << "A()" << endl; }
A(int32_t a) : a_(a) { cout << "Create A: " << a << endl; }
A(const A& oa) { a_ = oa.a_; cout << "Copy A: " << oa.a_ << endl; }
A(A& oa) { a_ = oa.a_; cout << "Copy A non-const: " << oa.a_ << endl; }
A(const A&& oa) { a_ = oa.a_; cout << "Move A: " << oa.a_ << endl; }
A(A&& oa) { a_ = oa.a_; cout << "Move A non-const: " << oa.a_ << endl; }
~A() { cout << "Del A: " << a_ << ", ptr: " << this << endl; }
int32_t a_;
};
void CreateAs(vector<pair<int32_t, A>>& as) {
as.reserve(3);
for (int32_t i = 0; i < 3; ++i) {
A* a = new A(i*i);
cout << "a ptr: " << &a << endl;
cout << "-----before insert----" << endl;
as.emplace_back(make_pair(i, move(*a)));
cout << "-----after insert-----" << endl;
}
}
void Test() {
vector<pair<int32_t, A>> as;
cout << "-----Create begin----" << endl;
CreateAs(as);
cout << "-----Create end------" << endl;
for (const auto& item : as) {
cout << item.first << "->" << item.second.a_ << endl;
}
}
int main(int32_t argc, char* argv[]) {
Test();
cout << "____end test____" << endl;
return 0;
}
make_pair constructs an A in a pair. emplace_back moves the pair and therefore A into the vector. The moved from pair is destroyed, also destroying the contained A.
To avoid any move, you might do
void CreateAs(std::vector<std::pair<int32_t, A>>& as) {
as.reserve(3);
for (int32_t i = 0; i < 3; ++i) {
as.emplace_back(i, i*i);
}
}
Demo
You currently have extra move with your extra make_pair.

How to pass a pointer to a structure to the constructor?

I want to pass the pointer to a structure(variables of this structure is an array with elements that have value x and y) to the constructor. Next I want to assign values x and y of each variable of this structure to the similar variable values of the structure in the class.
class Convex_quadrliteral
{
protected:
struct VC {
float x, y;
} vertice_coordinate[4];
public:
Convex_quadrliteral (VC *pointerVC);
};
Convex_quadrliteral::Convex_quadrliteral (VC *pointerVC) {
cout << "\nObject is being created" << endl;
for (int i = 0; i < 4; i++) //variable initialisation
{
vertice_coordinate[i].x = pointerVC[i].x;
vertice_coordinate[i].y = pointerVC[i].y;
}
//object's properties output
cout << "Properties: " << endl
<< "A (" << vertice_coordinate[0].x << ", " << vertice_coordinate[0].y << ")" << endl
<< "B (" << vertice_coordinate[1].x << ", " << vertice_coordinate[1].y << ")" << endl
<< "C (" << vertice_coordinate[2].x << ", " << vertice_coordinate[2].y << ")" << endl
<< "D (" << vertice_coordinate[3].x << ", " << vertice_coordinate[3].y << ")" << endl;
}
int main()
{
struct vertice_coordinate
{
float x, y;
};
vertice_coordinate *pointerVC = new vertice_coordinate[4];
for (int i = 0; i < 4; i++) {
pointerVC[i].x = 2;
pointerVC[i].y = 2;
}
Convex_quadrliteral figure_1(pointerVC);
I expect the output:
A(2, 2)
B(2, 2)
C(2, 2)
D(2, 2)
The output is error: no declaration matches 'Convex_quadrliteral::Convex_quadrliteral(Convex_quadrliteral::VC*)'C onvex_quadrliteral::Convex_quadrliteral (VC *pointerVC)
You re-define your VC struct, and even though the struct looks identical, the compiler will treat them as two different types. Define one struct and use it in both your class and in main.

Copy constructor issue [duplicate]

This question already has answers here:
C++: Argument Passing "passed by reference"
(4 answers)
Why is the copy constructor called when we pass an object as an argument by value to a method?
(3 answers)
Closed 6 years ago.
The program should resolve grade 1 equations in this specific manner. I had to use output messages for the constructors and destructors for better understanding of the code.
#include "stdafx.h"
#include <iostream>
using namespace std;
class Ec {
public: float a, b; //equation's parameters
public:
Ec() {float x, y; cout <<"a= "; cin >> x; cout << "b= ";
cin >> y; a = x; b = y; cout << "void constr\n";};
Ec(float x, float y) { a = x; b = y; cout << "param constr\n"; }
~Ec() { cout << "destr\n"; }
Ec(Ec &z) { a = z.a; b = z.b; cout << "cpy constr\n"; }
friend float half1(Ec); //function to return a/2
friend float half2(Ec); //function to return b/2
friend float sol1(Ec); //function to return the solution for the standard eq
friend float sol2(Ec); //function to return the sol for the /2 param eq
};
float half1(Ec ec1) { return (ec1.a / 2);}
float half2(Ec ec1) { return (ec1.b / 2); }
float sol1(Ec ec1) { float x; return x = -ec1.b / ec1.a; }
float sol2(Ec ec1) { float x2; return x2 = -half2(ec1) / half1(ec1); }
int main()
{
int x, y;
cout << "a= ";
cin >> x;
cout << "b= ";
cin >> y;
Ec ec1;
Ec ec2(x, y);
Ec ec3 = ec1;
//the couts display for ex:" ec 2x+1=0 has sol -0.5"
cout << "ec " << ec1.a << "x+ " << ec1.b << "=0 has sol " << sol1(ec1) << endl;
cout << "ec " << ec2.a << "x+ " << ec2.b << "=0 has sol " << sol1(ec2) << endl;
cout << "ec " << ec3.a << "x+ " << ec3.b << "=0 has sol " << sol1(ec3) << endl;
cout << "ec halved " << half1(ec1) << "x+ " << half2(ec1) << "=0 has sol " << sol2(ec1) << endl;
cout << "ec halved " << half1(ec2) << "x+ " << half2(ec2) << "=0 has sol " << sol2(ec2) << endl;
cout << "ec halved " << half1(ec3) << "x+ " << half2(ec3) << "=0 has sol " << sol2(ec3) << endl;
}
return 0;
}
Now, I have troubles understanding why after the first cpy constructor(for ec3) another cpy constructor is called then a destructor. What is it doing?
Your functions take Ec objects by value
float half1(Ec ec1) { return (ec1.a / 2);}
^
These will make function local copies that are then destroyed at the end of each function.
If you want to avoid making these copies, pass the arguments by const reference
float half1(Ec const& ec1) { return (ec1.a / 2);}
^

c++ Functions (with body) as Argument

I want to pass an function as argument. I know you can pass a function pointer like the first test in my example, but is it possible to pass a hold function (not a pointer) like my second test?
#include <iostream>
using namespace std;
/* variable for function pointer */
void (*func)(int);
/* default output function */
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
/* entry */
int main() {
cout << "Test Programm\n\n";
/* 1. Test - default output function */
cout << "my_default\n";
func = &my_default; // WORK! OK!
func(5);
/* 2. Test - special output function 2 */
cout << "my_func2\n";
func = void my_func1(int x) {
cout << "x =" << " " << x << endl << endl;
}; // WON'T WORK! FAILED!
func(5);
return 0;
}
In C++ 11, you can pass a lambda:
func = [](int x) { cout << "x =" << " " << x << endl << endl; };
EDIT: lambdas can return values:
func = [](int x)->int{ cout << "x =" << " " << x << endl << endl; return x; };
With c++11, you can write such code in a lot simpler way:
Instead of writing function signature use auto
auto func = &my_default; // WORK! OK!
func(5);
you can also use std::function objects to pass them around:
template<typename T>
void callme(std::function<T> f) {
f(6);
}
std::function<decltype(my_default)> func1 = &my_default;
func(5);
callme(func1);
and also you can use lambdas:
/* 2. Test - special output function 2 */
cout << "my_func2\n";
auto fun = [](int x) {
cout << "x =" << " " << x << endl << endl;
};
fun(5);
Even with return value it work:
#include <iostream>
using namespace std;
/* variable for function pointer */
int (*func)(int);
/* default output function */
int my_default(int x) {
//cout << "x =" << "\t" << x << endl << endl;
return x;
}
/* entry */
int main() {
cout << "Test Programm\n\n";
/* 1. Test - default output function */
cout << "my_default\n";
func = &my_default; // WORK! OK!
cout << func(5) << endl << endl;
/* 2. Test - special output function 2 */
cout << "my_func2\n";
func = [](int x) {
//cout << "x =" << " " << x << endl << endl;
return x;
};
cout << func(5) << endl << endl;
return 0;
}
You can uses lamdas:
std::function<int(int)> func2 = [](int i) { return i+4; };
std::cout << "func2: " << func2(6) << '\n';
if the body consists of the single return statement, the return type
is the type of the returned expression (after rvalue-to-lvalue,
array-to-pointer, or function-to-pointer implicit conversion)
If you lamda constains not single return statamen you should specify return type
std::function<int(int)> func2 = [=](int i) ->int {
if (globalVar)
return i*4;
else
return 4;
};
std::cout << "func2: " << func2(6) << '\n';

Cannot call class function (parameterized class)

#include<iostream>
using namespace std;
class a
{
private:
int x;
int y;
public:
int getx()
{
return x;
}
int gety()
{
return y;
}
a()
{
x = 100;
y = 100;
}
void xmin()
{
x--;
}
void ab(a x)
{
x.xmin(); x.xmin(); x.xmin(); x.xmin();
}
};
void main()
{
a xx;
a yy;
cout << "xx" << endl;
cout << "x : " << xx.getx() << "y : " << xx.gety()<<endl;
cout << "yy" << endl;
cout << "x : " << yy.getx() << "y : " << yy.gety()<<endl;
xx.ab(yy);
cout << "xx" << endl;
cout << "x : " << xx.getx() << "y : " << xx.gety() << endl;
cout << "yy" << endl;
cout << "x : " << yy.getx() << "y : " << yy.gety() << endl;
}
Why the function x.xmin() in void ab(a x) cannot be executed properly? (The value of x didn't change as the function of xmin() decrease the value of x by 1.
This is the simple version of my code so that will be easier to understand :)
void ab(a x)
That takes its argument by value. The function modifies a local copy of the argument, so the caller won't see any changes. If you want the function to modify the caller's object, then pass by reference:
void ab(a & x)
^