Different values of same variable in class - c++

#include<iostream>
using namespace std;
template<class T>
class vee
{
T* v;
int size;
public:
vee(int m)
{
v = new T[size=m];
cout<<size<<"\n";
}
vee(T* a)
{
cout<<size<<"\n";
for(int i=0;i<size;i++)
{
v[i]=a[i];
}
}
};
int main()
{
int x[]={1,2,3};
int y[]={2,3,4};
vee<int> v1(3);
v1=x;
return 0;
}
Why i am getting 2 different values of "size" ?
I have created a constructor to intilize the parameter size and it shows correct value in first constructor but it throws a garbage value in the second constructor ,why??

Why i am getting 2 different values of "size" ?
vee(T* a) is called converting constructor. When you write something like v1=x;, array x decays to a pointer, then it is converted to vee with provided converting constructor.
v1=x; is as if you wrote v1=vee<int>(x);
As you can see a temporary instance is created with undefined size and pointer, which is bad. Then you assign this instance to v1 which is worse.
If you do not want this autoconversion in the future, declare your constructor explicit
explicit vee(T* a)

When doing v1=x, you actually go and create new object, since you have not overrided the '=' operator.

but it throws a garbage value in the second constructor ,why??
vee(int m)
{
v = new T[size=m]; // in this constructor you set size
cout<<size<<"\n";
}
vee(T* a)
{
// but in this constructor you don't set size
cout<<size<<"\n";
for(int i=0;i<size;i++)
{
v[i]=a[i];
}
}
So, when you create a vee using the second constructor - and read from size - your program has undefined behaviour.

Related

for loop does not execute in C++

I was trying a random code to accept values using dynamic size. Surprisingly the for loop in the Accept function does not execute. Instead, the control directly leaves the function. Please explain what is the mistake here?
using namespace std;
#include<iostream>
class consequtive
{
public : int *ptr;
int size;
public :
consequtive(int size);
void Accept();
};
consequtive::consequtive(int size)
{
ptr = new int[size];
}
void consequtive :: Accept()
{
cout<<"Enter elements :: "<<endl;
for(int i = 0 ; i < size ; i++)
{
cin>>ptr[i];
}
}
int main()
{
int size = 0;
cout<<"Enter size ::";
cin>>size;
consequtive obj(size);
obj.Accept();
}
A few problems here.
You have a class parameter that has the same name as a member, which isn't really a problem, but is a source of confusion (As in your case).
You never set the member size to anything inside the constructor.
For number one, I would recommend renaming the class member size to size_ or something similar, since this creates a separation and makes the variables easier to distinguish from each other. As for as the second problem, I would change your constructor to the following:
consequtive::consequtive(int size) : size_(size) // Assuming the member is called `size_`
{
ptr = new int[size];
}
The code should work now, and uses a concept called member initializer lists. Not setting the variable size results in undefined behavior.
You forgot to initialize the size member variable.
You could do something like this:
consequtive::consequtive(int size)
: size(size),
ptr(new int[size])
{
}
You should also add a destructor to your class, to avoid a memory leak:
consequtive::~consequtive()
{
delete[] ptr;
}
This size in the class definition
public : int *ptr;
int size;
this size in the constructor implementation
consequtive::consequtive(int size)
and this size in the main function
int size = 0;
are all different variables. The latter two will both have the same value because of the way they are used, but one size can be changed to a different value without the other being aware. The bug in the asker's code is because the first size is never given a value and is used uninitialized.
Solution:
consequtive::consequtive(int size): ptr(new int [size]), size(size)
{
}
Here we are using the Member Initializer List. We don't gain much from its use in this case, but it is a very useful tool. More on that here: Why should I prefer to use member initialization list?
Be cautious when using a parameter or local variable with the same name as a member. The inner most identifier always wins so inside
consequtive::consequtive(int size): ptr(new int [size]), size(size)
{
// in here
}
the size variable is the parameter and not the member. You can this->size to explicitly state you want the member, but it is a better idea to not reuse the identifier at all. You could forget to prepend this-> and the compiler is unlikely to warn you of the mistake.

Un-initialized memory reached with vector of used defined struct

I was creating a vector of my bitpacked vectors, called xor_funcs, using the length and value constructor for vector.
This is the test that failed:
TEST(vectorInit, size3) {
const xor_func temp{false, {0,0,0}};
vector<xor_func> arr{3, temp};
for(xor_func& f : arr) {
EXPECT_EQ(3, f.size()) << f;
}
for(int i = 0; i < 3; i++) {
ASSERT_EQ(3, arr[i].size()) << "for i=" << i;
arr[i].set(i);
}
}
It seems that the size() call is accessing uninitialized memory, for vectors of length 3 or more, but not ones of size 2. Valgrind confirms that the memory is not recently stack'd, malloc'd or free'd.
The xor_func is defined as such:
class xor_func {
private:
boost::dynamic_bitset<> bitset;
bool negated;
public:
xor_func(const bool neg, const std::initializer_list<int> lst);
// That's defined in cpp
xor_func(const size_t size) : bitset(size), negated(false) {}
// Disallow the trivial constructor, since I don't want
// any 0 length xor_funcs existing by default.
// xor_func() : bitset(), negated(false) {}
xor_func(const bool negated, const boost::dynamic_bitset<> bitset)
: bitset(bitset), negated(negated) {}
// That's all the constructors.
// Snip
}
I didn't do anything with the default copy and move constructors.
What is going on, and why does my test fail?
As dyb said, vector<xor_func> arr{3, temp}; was being interpreted as
vector<xor_func> arr({xor_func{3}, temp}), as the 3 could be converted into a xor_func by a constructor implicitly, and then it could choose the initializer list version of the constructor to call.
If you look at Is C++11 Uniform Initialization a replacement for the old style syntax?, you can see that one of the downsides of uniform initialization syntax is exactly this bug. A more trivial example is
// std::string constructor prototype for reference
// fill (6)
string (size_t n, char c);
void main() {
string myString{65, 'B'};
cout << myString << endl;
}
This will print out "AB", instead of "BBBBBB...BBB", as it can convert 65 to 'A', and then it's as if we wrote myString{'A', 'B'}. To fix it, simply don't try and use the uniform initialization syntax for this call and replace it with
string myString(65, 'B');
Another way I could fix this bug is to change the constructor xor_func(const size_t size) to be explicit xor_func(const size_t size), which prevents the compiler from implicitly converting the 3 to an xor_func.
Oh, there's another great answer What does the explicit keyword mean in C++.

initialize multiple variables with constructor overloading

Let's say in a class a constructor is overloaded. Can multiple data members be initialized for the single object using different constructors of the same class?
eg :
class demo{
int size;
double k;
public:
demo(int s){
size=s;
}
demo(double p){
k = size+p;
}
void show(){
cout<<size<<" "<<k<<"\n";
}
};
int main(){
demo a = demo(0);
a = 4.7;
a.show();
return 0;
}
Is this possible?
No, once the object is constructed, it's constructed.
Let's go through your code and see what it does (assuming no optimizations, please note that many modern compilers will do some copy-elision even in debug or -O0 modes):
demo(0);
The code demo(0) calls the demo(int s) constructor. A temporary rvalue is created. So now we have a temporary object with the values:
size = 0
k = uninitialized
demo a = demo(0);
demo a is then created using an implicit copy constructor.
We now have a demo object named a with the following values:
size = 0
k = uninitialized
a = 4.7;
Because a is already constructed, this will call an implicit assignment-operator. The default assignment-operator will copy all the values from one object into the other object. This means the 4.7 needs to be converted into a demo object first. This is possible because of your demo(double p) constructor.
So a temporary demo object will be created with the values:
size = uninitialized
k = uninitialized + 4.7 = undefined
These values will be copied into a and so both of a's data members will be undefined.
Possible Solutions
songyuanyao's solution of using a constructor with multiple parameters is one good way of doing it.
Using setters is another way.
Either way, I would recommend having your constructors provide default values for your data-members.
demo(int s)
{
size = s;
k = 0.0; // or some other suitable value
}
Here's how you could create a setter.
void setK (double p)
{
k = size + p;
}
You could then do this:
int main ()
{
demo a (0) ;
a.setK (4.7) ;
a.show () ;
return 0 ;
}
I think you're after the Builder Pattern.
You should define a ctor which can take multiple parameters to initialize multiple data members:
demo(int s, double p) {
size = s;
k = size + p;
}
and then
int main() {
demo a(0, 4.7);
a.show();
return 0;
}

Allocating an array of a class c++

How would I go about allocating an array of a class without constructing the class, so I could fill up the array later?
I was originally trying to use
Myclass * array = new Myclass[N];
But it tries to construct Myclass to N.
First just declare it without allocating
Myclass * array[N];
when you need it
for(int i=0;i<N;i++){
array[i] = new Myclass(/*params*/);
}
But consider using std::vector/std::list if you must not have to manage memory yourself.
If you really want to do that, (not sure why), you could try
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass()
{ cout << "helo" << endl; }
};
int main(int argc, char *argv[])
{
int size = 4;
// Here is the trick, pointer to pointer.
MyClass **vec = new MyClass *[size];
cout << "before" << endl;
for (int i = 0; i < 4; ++i)
vec[i] = new MyClass;
// remember to free the vec
return 0;
}
Someone suggested placement new, so here it goes:
// allocate space
std::vector<unsigned char> mybuffer(N * sizeof(Myclass));
Myclass *array = reinterpret_cast<Myclass *>(&mybuffer[0]);
// when you're ready to use it
new( &array[0] ) Myclass(2);
new( &array[1] ) Myclass(3);
// etc...
// when you're done with it
array[0].~Myclass();
array[1].~Myclass();
// etc....
Of course, it is undefined behaviour to use array[x] before you have new'd it, or after you called the destructor.
This is generally something you wouldn't use as a solution to a "normal" problem. Consider actually defining a default constructor that does nothing, and having a function you call later which enhances the objects above their default state.
If you can use C++11, the optimal solution for you is probably std::vector<MyClass> with emplace-base insertions:
class MyClass {
public:
MyClass(int a, bool b, char c); // some non-default constructor
MyClass(double d); // another constructor
void bar();
};
void foo(int n) {
std::vector<MyClass> mv;
mv.reserve(n); // not even needed but beneficial if you know the final size.
// emplace_back uses perfect forwarding to call any arbitrary constructor:
mv.emplace_back(2, false, 'a');
mv.emplace_back(3, true, 'b');
mv.emplace_back(3.1415926535);
// can iterate vector easily:
for (auto &i : mv) {
i.bar();
}
// everything destructed automatically when the collection falls of scope ...
}
This creates the values in the collection directly without a copy and defers any construction of elements until you are ready, unlike new[], which makes a bunch of default objects at array-creation time. It is generally better than placement new as well, since it doesn't leave open opportunities for missed destruction or destructing an invalid memory location as well as being just easier to read.
Alternatively, you may use boost::optional.
So in your case:
std::vector<boost::optional<Myclass>> array(N);

Problem passing a list of objects to another class, C++

Below I have written a sample program that I have written to learn about passing a list of objects to another class. I talk about the problems I am having below.
#include <iostream>
#include <vector>
using namespace std;
class Integer_Class
{
int var;
public:
Integer_Class(const int& varin) : var(varin) {}
int get_var() { return var; }
};
class Contains_List
{
typedef Integer_Class* Integer_Class_Star;
Integer_Class_Star list;
public:
Contains_List(const Integer_Class_Star& listin) : list(listin) {}
Integer_Class* get_list() { return list; }
};
int main (int argc, char * const argv[])
{
// Create a vector to contain a list of integers.
vector<Integer_Class> list;
for(int i = 0; i < 10; i++)
{
Integer_Class temp_int(i);
list.push_back(temp_int);
}
This is where the errors start occuring. Could someone please look at the second class definition and the code below and shed some light on what I'm doing wrong. Thank you so much, as always!
// Import this list as an object into another object.
Contains_List final(list);
// Output the elements of the list by accessing it through the secondary object.
for(int i = 0; i < 10; i++)
{
cout << final.get_list()[i].get_var();
}
return 0;
}
You don't mention what sort of errors you are getting, but one very obvious problem with your code is that the constructor for Contains_List expects a pointer to Integer_Class while the parameter you are sending it (list) is of type vector<Integer_Class>.
A vector is not the same as an array, so you cannot pass it as pointer to the type it contains. Either change your constructor to accept a vector or pointer/reference to vector, or change the code that is causing you problems so that it sends it a pointer to an array.
The 'Contains_List' constructor takes in an 'Integer_Class*'
You declare 'list' to be of type 'vector', yet you pass it to the the 'Contians_List' constructor. You should change the 'Contains_List' class so that it holds a vector instead of an Integer_List array. The two are not interchangeable.
You could also change the vector to be an array of Integer_List's instead, if you so wished.