1

The code is as follow :

The Code :

#include <iostream>

using namespace std;

class pub
{
    string name;

    public:
    pub(string name):name(name){}    //Constructor
    void getName(string name){this->name = name;}
    string returnName(void){return name;}
};

int main(void)
{
    pub * p = new pub[5]; //Error-prone statement.

                          //Ignore for not having "delete" statement

    return 0;
}

The Question :

1.) In this case , is there any method for me to pass value to each dynamic memory I've allocated , or is it I have to set a default value to the constructor's argument in order to circumvent this problem ?

Thank you !

caramel1995
  • 2,968
  • 10
  • 44
  • 57
  • Normal naming convention would be to change `getName()` to `setName()` and `returnName()` to `getName()`. – TemplateRex Aug 14 '12 at 15:05
  • possible duplicate of [How do I declare an array of objects whose class has no default constructor?](http://stackoverflow.com/questions/2343558/how-do-i-declare-an-array-of-objects-whose-class-has-no-default-constructor) – tenfour Aug 14 '12 at 15:28

3 Answers3

3

If your compiler supports C++11 you could use std::vector and with an initializer list:

std::vector<pub> v { pub("1"), pub("2") };

See online demo https://ideone.com/Qp4uo .

Or std::array:

std::array<pub, 2> v = { { pub("1"), pub("2") } };

See online demo https://ideone.com/lBXUS .

Either of these also removes the burden of delete[]ing the dynamically allocated array.

hmjd
  • 120,187
  • 20
  • 207
  • 252
1

Apart from the somewhat unconvential naming convention that you used (I changed getName() to setName() and returnName() to getName(), and used trailing _ to denote private data members), using a `std::vector will do the memory management automatically for you:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class pub
{
public:
    pub(): name_("default") {}
    pub(string const& name): name_(name){}    //Constructor
    pub(const char* name): name_(name) {}
    void setName(string const& name){ name_ = name;}
    string getName(void) const {return name_;}

private:
    string name_;
};

int main(void)
{
    // initialize with 2 elements, then add 3 more default elements
    std::vector<pub> pub_vec { "bla", "bar" };
    pub_vec.resize(5);

    std::for_each(pub_vec.begin(), pub_vec.end(), [](pub const& elem){
        std::cout << elem.getName() << "\n";
    });

    return 0;
}   // 5 destructors automatically called

Note: adding an overloaded constructor that takes const char* allows you to use string literals to initialize your data.

Output on Ideone

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • Can you make `pub_vec` 5 long but only provide two default values (ie thus allowing the last three to be default constructed)? – Martin York Aug 14 '12 at 15:44
  • @LokiAstari If you add a default constructor for `pub` (setting the name to "default" or whatever), then simply doing `pub_vec.resize(5)` after the initialization will do what you want. – TemplateRex Aug 14 '12 at 17:54
  • I was wondering if `pub_vec(5) = { "bla", "bar" /* Implicit default construct 3 items */ };` would work. – Martin York Aug 14 '12 at 18:27
  • @LokiAstari No that syntax won't compile. The closest that does compile is `std::vector pub_vec(5); pub_vec = { "bla", "bar" };` but then the final elements get truncated. I think the single `pub_vec.resize(5)` is good enough, because it scales very well for larger trailing default strings. – TemplateRex Aug 14 '12 at 18:33
0

Use std::vector<pub>. It doesn't require the default constructor.

E.g.

std::vector<pub> vec(5, pub("xyz"));

creates a vector with 5 equal elements.

Andriy
  • 8,486
  • 3
  • 27
  • 51