What ways are there to call a constructor in C++? - c++

//I have a for loop that should construct an array of a certain class "Line" from two arrays of floats
for (int i=0; i<length; i++) Linearray[i](a[i], b[i]);
//my constructor function for line is:
pine::pine(float a, float b) {
st = a;
e = b;
}
//the error I'm getting is that I have no call operator defined.
//It's a little complicated to explain, so say all I can use is this constructor to fill that array.
//also assume arrays a and b are full of floats.

This Linearray[i](a[i], b[i]); tries to call the call operator operator()() (see also What are C++ functors and their uses?) from the Line class (which you probably haven't defined, hence the error) at the ith element in that list. You'd need to assign a new instance to call a constructor there:
Linearray[i] = Line(a[i], b[i]);

Although your question is already answered by Timo. Here is another way to achieve same goal
#include <iostream>
using namespace std;
class Line{
private:
int start, end;
public:
Line(){}
Line(float a, float b) {
start = a;
end = b;
}
};
int main() {
std::cout << "Hello World!\n";
int N = 5;
Line * arr = (Line*)malloc(sizeof(Line) * N);
for(auto i=0; i<N; i++){
arr[i] = Line(5,6);
}
}

Related

Having a problem with getting the right value with private variable

This is a program that takes an array and print the sum of the odd (named m_sumOdd) and even (named m_sumEven) numbers of that array using class. However when i run it and enter some values like (4, 6, 9, 3, 1) the m_sumEven returns 10 and m_sumOdd returns 2037769787. What's the problem with m_sumOdd ?
#include <iostream>
#include <string>
class myClass {
private:
int m_sumEven;
int m_sumOdd;
public:
myClass() {
m_sumEven = 0;
m_sumOdd = 0;
}
myClass(int arr[]) {
for (int i = 0; i < 5; i++)
{
if (arr[i] % 2 == 0) {
m_sumEven += arr[i];
}
else if (arr[i] % 2 != 0) {
m_sumOdd += arr[i];
}
}
print();
}
void print() {
std::cout << m_sumEven << "\t" << m_sumOdd << std::endl;
}
};
int main(){
int main_arr[5];
for (int j = 0; j < 5; j++)
{
std::cin >> main_arr[j];
}
myClass obj(main_arr);
std::cin.get();
}
From your comment:
the problem is from my uni textbook and it specify that the private variables shall be initialized in the default constructor and the other constructor find the sum
I'm not sure what solution the textbook is looking for, but there is a mechanism that allows one constructor to use another.
class myClass {
private:
int m_sumEven;
int m_sumOdd;
public:
myClass() {
m_sumEven = 0;
m_sumOdd = 0;
}
myClass(int arr[]): myClass() { // <-------
....
This is called delegating constructors. This makes your myClass(int arr[]) constructor use the myClass() constructor before continuing on.
When you do not initialize your variable in C++, the default value of that variable is whatever garbage value happens to already be in that memory location. So if you initialize your privates variables as zeros (as in your non-parameterized constructor), your problem will be solved.
The second constructor doesn't initialize the private variables like the first one.
m_sumEven = 0;
m_sumOdd = 0;
Put these to the second constructor as well.
Even better, put them at the declaration:
int m_sumEven = 0;
int m_sumOdd = 0;
And now you don't need the first constructor.
Unrelated: consider using std::initializer_list instead. This provides you a safe way to know how many items are passed to the constructor, while now you have a fixed 5 in mind which may change later.

how to copy Int array to int pointer using constructor in C++

I am trying to insert int array x to int *v. here is my code . please provide me with optimal solutions and the reason behind it.
there is an error in this line. Instead of copying array value its taking garbage value. line v1=x;
class vector
{
int *v;
int size;
public:
vector(int m)
{
v = new int[size = m];
for (int i = 0; i < size; i++)
v[i] = 0;
}
vector(int *a)
{
for (int i = 0; i < size; i++)
v[i] = a[i];
}
int operator *(vector &y)
{
int sum = 0;
for (int i = 0; i < size; i++)
sum += v[i] * y.v[i];
return sum;
}
void disp()
{
for (int i = 0; i < size; i++)
cout << v[i] << " ";
cout << "\n";
}
};
int main()
{
clrscr();
int x[3] = { 1,2,3 };
int y[3] = { 4,5,6 };
vector v1(3);
//v1.disp();
vector v2(3);
v2.disp();
v1 = x;
v1.disp();
//v2=y;
v2.disp();
int r = v1 * v2;
cout << "R = " << r;
getch();
return 0;
}
You forgot to add the assignment operator in your vector class:
vector & operator=(int *a)
{
for (int i = 0; i < size; i++)
v[i] = a[i];
return *this;
}
In the the line
v1=x;
May be, you are expecting it to invoke the second constructor which takes int* as argument. But it won't happen.
It can be seen as Type Conversion from Basic type to Class type. where we expect appropriate constructor will get invoked.
see http://www.hexainclude.com/basic-to-class-type-conversion/
But remember, Constructor will be invoked only once after the creation of object.
Here, in the line
vector v1(3);
the first constructor was already invoked. Then the line
v1=x;
won't invoke the second constructor now.
For every class, = operator is default overloaded . That is the reason why we can easily assign objects to one another.
Therefore, the line v1=x invokes default overloaded assignment = operator.
Here, it treats address of array x i.e., &x[0] as address of class object. As it is not address of vector class object
=> it results a Segmentation fault.
YOUR ANSWER
To assign int array to int pointer i.e., to the member variable int* v of the vector class,
overload assignment operator = inside the class .
or
Initialize the class object to array in first line itself. i.e.,
vector v1=x; // modify the class constructor to have size as a constant.

Why does this program create an output like this?

Why does this program write 45, 125 and 300?
I know for 45 and 300, I'm more interested in a case sum1(arrD), where program writes 125.
I hope somebody will know.
#include <iostream>
using namespace std;
class B{
public:
B(): b(bCounter++){}
int b;
static int bCounter;
};
int B::bCounter = 0;
class D : public B{
public:
D() : d(bCounter){}
int d;
};
const int N = 10;
B arrB[N];
D arrD[N];
int sum1(B* arr){
int s = 0;
for (int i=0; i<N; i++) s+=arr[i].b;
return s;
}
int sum2 (D* arr){
int s = 0;
for (int i = 0; i<N; i++) s+= arr[i].b + arr[i].d;
return s;
}
int main(){
cout<<" result is: "<<sum1(arrB)<<endl;
cout<<" result is: "<<sum1(arrD)<<endl;
cout<<" result is: "<<sum2(arrD)<<endl;
system("pause");
return 0;
}
The static arrays B arrB[N] and D arrD[N] seem to be causing the trouble here.
Arrays aren't polymorphic; you can pass a D* to a function expecting a B* only if it expects a single element. (Try using std::vector, and you'll get a compile time error.) The reason is simple: the pointer arithmetic needed to access the array elements is based on the static size of the pointed to element, so each time you do i++ in the loop in sum1, and then index, the compiler calculates the address of your element as arr + i * sizeof(B) (at the machine level, where arr is a pure, untyped address).
Trying to do pointer arithmetic when the static type is not the same as the dynamic type is undefined behavior, so as far as the language is concerned, anything can happen.
And this is yet another reason not to use C style arrays.
The problem is that the arrays do not contain pointers to the objects but whole objects.
So when you use the D array via a pointer to the base class, (as James noted) the behaviour is undefined.
What in practice probably happens on most systems: The pointer-based loop only iterates over half the D objects, because a B object contains only one int, while the D objects contain two of them.
So the loop looks only at the first 5 D objects:
b / d
10/11
11/12
12/13
13/14
14/15
which sums up to the ominous 125.
I think it's incorrect to cast an array of D to an array of B. The stride isn't correct. This is why you see these repeats of values.
Run following code , you'll know the reason
#include <iostream>
using namespace std;
class B{
public:
B(): b(bCounter++){
cout<<"B called\n";
}
int b;
static int bCounter;
};
int B::bCounter = 0;
class D : public B{
public:
D() : d(bCounter){
cout<<"D called\n";
}
int d;
};
const int N = 10;
B arrB[N];
D arrD[N];
int sum1(B* arr){
int s = 0;
for (int i=0; i<N; i++)
{
cout<<arr[i].b<<"\n";
s+=arr[i].b;
}
return s;
}
int sum2 (D* arr){
int s = 0;
for (int i = 0; i<N; i++) s+= arr[i].b + arr[i].d;
return s;
}
int main(){
//cout<<" result is: "<<sum1(arrB)<<endl;
cout<<" result is: "<<sum1(arrD)<<endl;
//cout<<" result is: "<<sum2(arrD)<<endl;
system("pause");
return 0;
}

second Constructor called in c++ ( wrong output)

I am trying to do a simple thing but suddenly stuck in between .
Here in my code I am trying to call a constructor in which i would only pass the length, my first constructor initializes an array of size = length with all elements 0.
Then i am passing the array to the constructor to give the previously defined array its values
here is the sample :
class myvector
{
int *arr;
int length;
public :
myvector(int);
myvector(int *);
};
myvector :: myvector (int len)
{
arr = new int [length = len];
for ( int i=0;i< length;i++)
{
arr[i] = 0;
}
}
myvector :: myvector ( int *ex)
{
for ( int i=0;i< length;i++)
{
cout << ex[i] << " " << length <<" ";
arr[i] = ex[i];
cout << arr[i]<< " ";
}
}
int main()
{
myvector v1(5);
int x[5] = {2,3,4,45,6};
v1 = x;
}
Here in my second constructor length which was defined in first constrcutor lost its values , also array arr loses its values
Did I do something ?
Please elaborate me on this
I don't think you quite get what the circumstances are in which constructors are invoked. The line v1 = x doesn't put the values into the memory allocated during the first constructor call. Rather, it constructs a new myvector (using the second constructor) and copies it into v1. The stuff you do during the first constructor call is lost.
It sounds like you want to define an assignment operator, not a constructor taking an int* argument. Also, in general you should declare single-argument constructors as explicit to prevent this sort of thing from happening accidentally.
First of all, when specifying a size of array like this, you should provide a constant value. See here. And I really encourage you to use std::vector<> for such tasks.
But anyway, like Sneftel mentioned, seems like you want to define an assignment operator (see here for more information about overloading operators in tasks like yours).
Here how I'd implemented it(NOT and ideal solution, but it works, and gives a basic idea):
#include <iostream>
using namespace std;
class myvector
{
int *arr;
int length;
public :
//I completely removed second constructor
myvector(int);
~myvector();
void operator=(const int* otherArray);
void printArray();
};
myvector::myvector (int len)
{
length = len;
arr = new int[length]; // This is the way, how you can handle a non constant array sizes
for ( int i=0;i< length;i++)
{
arr[i] = 0;
}
}
void myvector::printArray()
{
for(unsigned i = 0; i < length; ++i)
cout<<"arr["<<i<<"] = "<<arr[i]<<endl;
}
//Here's an overloaded '=' operator.
//int x[5] = {2,3,4,45,6};
//myvector v;
//v = x; - here this function is called
void myvector::operator=(const int* otherArray)
{
for(unsigned i = 0; i < length; ++i)
arr[i] = otherArray[i];
}
myvector::~myvector()
{
delete []arr; // You should ALWAYS delete what you allocated with new
}
int main()
{
myvector v1(5);
int x[5] = {2,3,4,45,6};
v1 = x;
v1.printArray();
}

Computing the scalar product of two vectors in C++

I am trying to write a program with a function double_product(vector<double> a, vector<double> b) that computes the scalar product of two vectors. The scalar product is
$a_{0}b_{0}+a_{1}b_{1}+...+a_{n-1}b_{n-1}$.
Here is what I have. It is a mess, but I am trying!
#include <iostream>
#include <vector>
using namespace std;
class Scalar_product
{
public:
Scalar_product(vector<double> a, vector<double> b);
};
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
int main() {
cout << product << endl;
return 0;
}
Unless you need to do this on your own (e.g., writing it is homework), you should really use the standard algorithm that's already written to do exactly what you want:
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<double> a {1, 2, 3};
std::vector<double> b {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(std::begin(a), std::end(a), std::begin(b), 0.0);
return 0;
}
Note that while begin(a) and end(a) are new in C++11, std::inner_product has been available since C++98. If you are using C++ 98 (or 03), it's pretty easy to write your own equivalent of begin and end to work with arrays though:
template <class T, size_t N>
T *begin(T (&array)[N]) {
return array;
}
template <class T, size_t N>
T *end(T (&array)[N]) {
return array + N;
}
Using these, a C++ 98 version of the previous code could look something like this:
int main() {
double a[] = {1, 2, 3};
double b[] = {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(begin(a), end(a), begin(b), 0.0);
return 0;
}
Note that the begin and end above will only work for arrays, where the begin and end in C++11 (and later) will also work for normal collection types that define a .begin() and .end() (though it's trivial to add overloads to handle those as well, of course):
template <class Coll>
typename Coll::iterator begin(Coll const& c) { return c.begin(); }
template <class Coll>
typename Coll::iterator end(Coll const& c) { return c.end(); }
You can delete the class you have defined. You don't need it.
In your scalar_product function:
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
It's almost there. You don't need 2 loops. Just one.
double scalar_product(vector<double> a, vector<double> b)
{
if( a.size() != b.size() ) // error check
{
puts( "Error a's size not equal to b's size" ) ;
return -1 ; // not defined
}
// compute
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
product += (a[i])*(b[i]); // += means add to product
return product;
}
Now to call this function, you need to create 2 vector objects in your main(), fill them with values, (the same number of values of course!) and then call scalar_product( first_vector_that_you_create, second_vector_object );
While you have been presented many solutions that work, let me spin up another variation to introduce a couple of concepts that should help you writing better code:
class are only needed to pack data together
a function should check its preconditions as soon as possible, those should be documented
a function should have postconditions, those should be documented
code reuse is the cornerstone of maintenable programs
With that in mind:
// Takes two vectors of the same size and computes their scalar product
// Returns a positive value
double scalar_product(std::vector<double> const& a, std::vector<double> const& b)
{
if (a.size() != b.size()) { throw std::runtime_error("different sizes"); }
return std::inner_product(a.begin(), a.end(), b.begin(), 0.0);
} // scalar_product
You could decide to use the inner_product algorithm directly but let's face it:
it requires four arguments, not two
it does not check for its arguments being of the same size
so it's better to wrap it.
Note: I used const& to indicate to the compiler not to copy the vectors.
You seem to want to make a class specifically for vectors. The class I made in my example is tailored to 3 dimensional vectors, but you can change it to another if desired. The class holds i,j,k but also can conduct a scalar products based on other MathVectors. The other vector is passed in via a C++ reference. It is hard to deduce what the question was, but I think this might answer it.
#include <iostream>
using namespace std;
class MathVector
{
private:
double i,j,k;
public:
MathVector(double i,double j,double k)
{
this->i=i;
this->j=j;
this->k=k;
}
double getI(){return i;}
double getJ(){return j;}
double getK(){return k;}
double scalar(MathVector &other)
{
return (i*other.getI())+(j*other.getJ())+(k*other.getK());
}
};
int main(int argc, char **argv)
{
MathVector a(1,2,5), b(2,4,1);
cout << a.scalar(b) << endl;
return 0;
}
Here is the code that you should have. I see you have used class in your code, which you do not really need here. Let me know if the question required you to use class.
As you are new and this code might scare you. So, I will try to explain this as I go. Look for comments in the code to understand what is being done and ask if you do not understand.
//Scalar.cpp
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
/**
This function returns the scalar product of two vectors "a" and "b"
*/
double scalar_product(vector<double> a, vector<double> b)
{
//In C++, you should declare every variable before you use it. So, you declare product and initialize it to 0.
double product = 0;
//Here you check whether the two vectors are of equal size. If they are not then the vectors cannot be multiplied for scalar product.
if(a.size()!=b.size()){
cout << "Vectors are not of the same size and hence the scalar product cannot be calculated" << endl;
return -1; //Note: This -1 is not the answer, but just a number indicating that the product is not possible. Some pair of vectors might actually have a -1, but in that case you will not see the error above.
}
//you loop through the vectors. As bobo also pointed you do not need two loops.
for (int i = 0; i < a.size(); i++)
{
product = product + a[i]*b[i];
}
//finally you return the product
return product;
}
//This is your main function that will be executed before anything else.
int main() {
//you declare two vectors "veca" and "vecb" of length 2 each
vector<double> veca(2);
vector<double> vecb(2);
//put some random values into the vectors
veca[0] = 1.5;
veca[1] = .7;
vecb[0] = 1.0;
vecb[1] = .7;
//This is important! You called the function you just defined above with the two parameters as "veca" and "vecb". I hope this cout is simple!
cout << scalar_product(veca,vecb) << endl;
}
If you are using an IDE then just compile and run. If you are using command-line on a Unix-based system with g++ compiler, this is what you will do (where Scalar.cpp is the file containing code):
g++ Scalar.cpp -o scalar
To run it simply type
./scalar
You should get 1.99 as the output of the above program.