Class initialization fails with default constructor - c++

I am learning about classes in C++ and I created a simple one that just creates an interval from int a to int b, using a dynamic int array. Here's the code:
Interval::Interval() {
a_ = 0;
b_ = 0;
interval = new int[2];
for (int i = 0; i <= 1; ++i) {
interval[i] = 0;
}
}
Interval::Interval(int a, int b) {
if (a > b) Interval(); // doesn't seem to work?
else if (a == b) {
a_ = a;
b_ = b;
interval = new int[2];
for (int i = 0; i <= 1; ++i) {
interval[i] = a;
}
} else {
a_ = a;
b_ = b;
int size = b - a + 1;
interval = new int[size];
for (int i = 0; i < size; ++i) {
interval[i] = a++;
}
}
}
Interval::~Interval() {
delete[] interval;
cout << "Destructed\n";
}
However, on this part here:
if (a > b) Interval();
It doesn't seem to create it. Where am I wrong?
Edit: As answered by molbdnilo, I was simply creating a separate object inside of the scope of the constructor without assigning or doing anything with it.

Noting that your default constructor is equivalent to Interval(0,0), you can reuse the non-default constructor instead, by forwarding to it:
Interval::Interval() : Interval(0,0) {}
Interval::Interval(int a, int b)
: a_(a <= b ? a : 0),
b_(a <= b ? b : 0)
{
if (a_ == b_) {
interval = new int[2] {a_, a_};
} else {
int size = b_ - a_ + 1;
interval = new int[size];
for (int i = 0; i < size; ++i) {
interval[i] = a_ + i;
}
}
}

This line
if (a > b) Interval();
when the condition is met, it default constructs a temporary Interval which is destroyed at the end of the line.
Your code looks rather compilcated for what it does. The array should rather be a std::vector such that you need not mess around with manual memory allocations. Anyhow, to get what you want "I want default constructed object in that case." the easy fix is the following:
if (a > b) {
a = 0;
b = 0;
}
if (a == b) {
a_ = a;
b_ = b;
interval = new int[2];
for (int i = 0; i <= 1; ++i) {
interval[i] = a;
}
} else { ...

Related

Using for loop inside declaration of variable

Can I use for loop inside declaration a variable?
int main() {
int a = {
int b = 0;
for (int i = 0; i < 5; i++) {
b += i;
}
return b;
};
printf("%d", a);
}
You can use a lambda:
int main() {
int a = []{
int b = 0;
for (int i = 0; i < 5; i++) {
b += i;
}
return b;
}();
printf("%d", a);
}
It's important to note that you have to immediately execute it otherwise you attempt to store the lambda. Therefore the extra () at the end.
If you intent to reuse the lambda for multiple instantiations, you can store it separately like this:
int main() {
auto doCalculation = []{
int b = 0;
for (int i = 0; i < 5; i++) {
b += i;
}
return b;
};
int a = doCalculation();
printf("%d", a);
}
If you need it in more than one scope, use a function instead.
actually has been prepared by C++ committee..
constexpr has many usefulness not yet exlpored
constexpr int b(int l) {
int b=0;
for (int i = 0; i < l; i++)
b += i;
return b;
}
int main() {
constexpr int a = b(5);
printf("%d", a);
}

How to initialize dynamic array inside a class?

I wish to initialize a multidimensional, dynamic array inside a class. But, I am getting an error.
I have seen several examples on the net. They seem to be difficult. I am new to coding. I would like a simple solution if possible.
class myp
{
int ntc = 5;
public:
double** y = new double*[ntc];
for(int i = 0; i < ntc; ++i)
y[i] = new int[3];
};
int main()
{
int x;
myp mp;
mp.y[1][1] = 3;
cout<<mp.y[1][1]<<endl;;
return 0;
}
test.cpp:12:2: error: expected unqualified-id before ‘for’
for(int i = 0; i < ntc; i++)
^~~
test.cpp:12:17: error: ‘i’ does not name a type
for(int i = 0; i < ntc; i++)
^
test.cpp:12:26: error: ‘i’ does not name a type
for(int i = 0; i < ntc; i++)
You need to do class initialisation in the constructor function, and cleanup in the destructor.
class myp
{
int m_numColumns;
int m_numRows;
double** y;
public:
// overload array operators
double* operator [] (size_t row) { return y[row]; }
const double* operator [] (size_t row) const { return y[row]; }
// return dimensions of array
int numColumns() const { return m_numColumns; }
int numRows() const { return m_numRows; }
// constructor
myp(int nc, int nr) : m_numColumns(nc), m_numRows(nr)
{
y = new double*[m_numRows];
for(int i = 0; i < m_numColumns; ++i)
y[i] = new int[m_numColumns];
}
// destructor
~myp()
{
for(int i = 0; i < m_numColumns; ++i)
delete [] y[i];
delete [] y;
}
// be careful of the copy ctor. I'm deleting it in this case!
myp(const myp&) = delete;
// edit: as per user4581301's suggestion
myp() = delete;
myp(myp&&) = delete; // remove move ctor
myp& operator = (const myp&) = delete; // remove assignment
myp& operator = (myp&&) = delete; // remove move assignment
};
int main()
{
myp mp(5, 3);
mp[1][1] = 3;
cout << mp[1][1]<<endl;
return 0;
}
Just For Run.
class myp
{
int ntc = 5;
public:
double **y;
void initArray()
{
y = new double*[ntc];
for(int i = 0; i < ntc; ++i)
y[i] = new double[3]; // i change this line [new int] to [new double]tv
}
};
int main()
{
int x;
myp mp;
mp.initArray();
mp.y[1][1] = 3;
cout<<mp.y[1][1]<<endl;;
return 0;
}
using constructor & destructor
class myp
{
int ntc = 5;
public:
double **y;
myp() // run at created
{
y = new double*[ntc];
for(int i = 0; i < ntc; ++i)
y[i] = new double[3];
}
~myp() // run at the end of life cycle
{
/* free memory here */
}
};
int main()
{
int x;
myp mp; // myp() called
mp.y[1][1] = 3;
cout<<mp.y[1][1]<<endl;
return 0;
}
using constructor with parameter, for dynamic size
class myp
{
// int ntc = 5; // using at created
public:
double **y;
myp(int ntc, int size) // run at created
// if you want to use only myp mp;
// myp(int ntc = 5, int size = 3) {} will be helpful
{
y = new double*[ntc];
for(int i = 0; i < ntc; ++i)
y[i] = new double[size];
}
~myp() // run at the end of life cycle
{
/* free memory here */
}
};
int main()
{
int x;
myp mp(5, 3); // myp(int, int) called
mp.y[1][1] = 3;
cout<<mp.y[1][1]<<endl;
return 0;
}

How to avoid returning pointers in a class

Assume I have a class A that has say 3 methods. So the first methods assigns some values to the first array and the rest of the methods in order modify what is computed by the previous method. Since I wanted to avoid designing the methods that return an array (pointer to local variable) I picked 3 data member and store the intermediate result in each of them. Please note that this simple code is used for illustration.
class A
{
public: // for now how the class members should be accessed isn't important
int * a, *b, *c;
A(int size)
{
a = new int [size];
b = new int [size];
c = new int [size];
}
void func_a()
{
int j = 1;
for int(i = 0; i < size; i++)
a[i] = j++; // assign different values
}
void func_b()
{
int k = 6;
for (int i = 0; i < size; i++)
b[i] = a[i] * (k++);
}
void func_c()
{
int p = 6;
for int (i = 0; i < size; i++)
c[i] = b[i] * (p++);
}
};
Clearly, if I have more methods I have to have more data members.
** I'd like to know how I can re-design the class (having methods that return some values and) at the same time, the class does not have the any of two issues (returning pointers and have many data member to store the intermediate values)
There are two possibilities. If you want each function to return a new array of values, you can write the following:
std::vector<int> func_a(std::vector<int> vec){
int j = 1;
for (auto& e : vec) {
e = j++;
}
return vec;
}
std::vector<int> func_b(std::vector<int> vec){
int j = 6;
for (auto& e : vec) {
e *= j++;
}
return vec;
}
std::vector<int> func_c(std::vector<int> vec){
//same as func_b
}
int main() {
std::vector<int> vec(10);
auto a=func_a(vec);
auto b=func_b(a);
auto c=func_c(b);
//or in one line
auto r = func_c(func_b(func_a(std::vector<int>(10))));
}
Or you can apply each function to the same vector:
void apply_func_a(std::vector<int>& vec){
int j = 1;
for (auto& e : vec) {
e = j++;
}
}
void apply_func_b(std::vector<int>& vec){
int j = 6;
for (auto& e : vec) {
e *= j++;
}
}
void apply_func_c(std::vector<int>& vec){
// same as apply_func_b
}
int main() {
std::vector<int> vec(10);
apply_func_a(vec);
apply_func_b(vec);
apply_func_c(vec);
}
I'm not a big fan of the third version (passing the input parameter as the output):
std::vector<int>& func_a(std::vector<int>& vec)
Most importantly, try to avoid C-style arrays and use std::vector or std::array, and don't use new, but std::make_unique and std::make_shared
I'm assuming you want to be able to modify a single array with no class-level attributes and without returning any pointers. Your above code can be modified to be a single function, but I've kept it as 3 to more closely match your code.
void func_a(int[] arr, int size){
for(int i = 0; i < size; i++)
arr[i] = i+1;
}
void func_b(int[] arr, int size){
int k = 6;
for(int i = 0; i < size; i++)
arr[i] *= (k+i);
}
//this function is exactly like func_b so it is really unnecessary
void func_c(int[] arr, int size){
int p = 6;
for(int i = 0; i < size; i++)
arr[i] *= (p+i);
}
But if you just want a single function:
void func(int[] arr, int size){
int j = 6;
for(int i = 0; i < size; i++)
arr[i] = (i+1) * (j+i) * (j+i);
}
This solution in other answers is better, if you are going to allocate memory then do it like this (and test it!) also if you are not using the default constructor and copy constructor then hide them, this will prevent calling them by accident
class A{
private:
A(const &A){}
A() {}//either define these or hide them as private
public:
int * a, *b, *c;
int size;
A(int sz) {
size = sz;
a = new int[size];
b = new int[size];
c = new int[size];
}
~A()
{
delete[]a;
delete[]b;
delete[]c;
}
//...
};

Big integer calculator c++

So far I've got an add, subtract and print function as well as a constructor that initializes to zero the array. For some reason the operations(+ and -) made alot of sense to me(i think) so I kind of got ahead of my self and am not too sure how to initialize a big integer, could I get some help with a function such as
void assign(const bigint & A) or something like that? Also if there is something already wrong with my code please tell me. Thanks
const int size=30; //just to make things easier, will change to something big later
class bigint
{
int digits[size];
public:
// initializes to zero
bigint()
{
for (int i = 0; i < size; i++)
digits[i] = 0;
}
// prints a big int
void print()
{
bigint B;
for (int i = size - 1; i >= 0; i--)
{
int dig = B.digits[i];
if (dig != 0)
std::cout << dig;
}
}
// subtracts a bigint(B) from another(A)
void subtract(bigint & A, bigint & B)
{
for (int i = 0, borrow = 0; i < size; i++)
{
if (borrow = ((A.digits[i] -= B.digits[i] + borrow) < 0))
{
A.digits[i] += 10;
}
}
}
// adds a bigint(A) to another(B)
void add(bigint & A, bigint & B)
{
for (int i = 0, carry = 0; i < size; i++)
{
if (carry = ((A.digits[i] += B.digits[i] + carry) < 9))
{
A.digits[i] -= 10;
}
}
}
};

What is the meaning of `A vec*[5] = new B*[5]`

Array memory Allocation doesn't work
I saw the following code and found that it doesn't compile.
Is the code in the OP correct?
Thank you
class A {
};
class B : public A {
int num;
};
int main() {
/* Original Post
error: expected initializer before ‘*’ token
A vec*[5] = new B*[5];
A vec*[5] = new B*[5]; // <<< I don't understand this line
for(int i = 0; i < 5; i++)
{
vec[i] = new B();
}
*/
// My modified version
A* vec[5];
for(int i = 0; i < 5; i++)
{
vec[i] = new B();
}
return 0;
}