Array of Objects - std::array - constructor

I'm writing a periodic table program to help me understand classes.
I want to be able to display/sort the elements by several properties such as whether it's a metal, nonmetal, or metalloid. I'm not sure hwo to do it, but my first guess was to create an array of objects; however, I'm having problems using my constructor to set the values.

Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Element{
    public:
       enum class groupNames {  HYDROGEN, ALKALI, ALKALINE, GROUP_THREE, GROUP_FOUR, GROUP_FIVE,
                                GROUP_SIX, GROUP_SEVEN, GROUP_EIGHT, GROUP_NINE, GROUP_TEN,
                                GROUP_ELEVEN,GROUP_TWELVE, GROUP_THIRTEEN, GROUP_FOURTEEN,
                                GROUP_FIFTEEN, CHALCOGEN, HALOGEN, NOBLE_GAS
                                };
        enum class orbitals {ORBITAL_NOTSET, S_ORBITAL, P_ORBITAL, D_ORBITAL, F_ORBITAL};
        enum class metal_status {METAL = 0, METALLOID, NONMETAL};
        Element();
        Element(int aNumber, int pNumber,groupNames groupnames, metal_status MetalStatus, orbitals Orbital,std::string eName, std::string eSybol);
        void displayProperties();

    private:
        groupNames groupNumber;
        orbitals orbital;
        metal_status metalStatus;
        std::string elementSymbol;
        std::string elementName;
        int atomicNumber;
        int periodNumber;
};

Element::Element()
{
    atomicNumber = 0;
    periodNumber = 0;
    groupNumber = groupNames::HYDROGEN;
    metalStatus = metal_status::METAL;
    orbital = orbitals::ORBITAL_NOTSET;
    elementName = "NULL";
    elementSymbol = "NULL";
}

Element::Element(int aNumber, int pNumber,groupNames groupnames, metal_status MetalStatus, orbitals Orbital,std::string eName, std::string eSymbol)
{
    groupNumber = groupnames;
    metalStatus = MetalStatus;
    orbital = Orbital;
    atomicNumber = aNumber;
    periodNumber = pNumber;
    elementName = eName;
    elementSymbol = eSymbol;
}

void Element::displayProperties()
{
    std::cout << elementName << ", " << elementSymbol << "\n"
              << "Group Number: " << as_integer(groupNumber) << "\n"
              << "Metal Status: " << as_integer(metalStatus) << "\n"
              << "Orbital: "      << as_integer(orbital) << "\n"
              << "Atomic Number: "<< atomicNumber << "\n"
              << "Period Number: "<< periodNumber;
}


Previous Method of Initialization
1
2
Element Hydrogen(1,1, group::HYDROGEN, metalStat::NONMETAL, orbital::S_ORBITAL, "Hydrogen", "H");
Element Helium(2, 1, group::NOBLE_GAS, metalStat::NONMETAL, orbital::S_ORBITAL, "Helium", "He");


std::array Method -- Problem!
1
2
3
4
5
std::array<Element, 115> Elements =
{
    Elements[0],
    Elements[1](1,1, group::HYDROGEN, metalStat::NONMETAL, orbital::S_ORBITAL, "Hydrogen", "H")
};


Error: error: no match for call to '(std::array<Element, 115u>::value_type {aka Element}) (int, int, Element::groupNames, Element::metal_status, Element::orbitals, const char [9], const char [2])'
Last edited on
You are attempting to initialize the elements of a new array object with the elements of that same not yet existing array object.
int foo = foo; // error

std::array<> is a simple aggregate type.
We initialize it just we would initialize a struct holding a C-style array as the only member.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <string>
#include <array>
#include <iostream>

class Element{
    public:
       enum class groupNames {  HYDROGEN, ALKALI, ALKALINE, GROUP_THREE, GROUP_FOUR, GROUP_FIVE,
                                GROUP_SIX, GROUP_SEVEN, GROUP_EIGHT, GROUP_NINE, GROUP_TEN,
                                GROUP_ELEVEN,GROUP_TWELVE, GROUP_THIRTEEN, GROUP_FOURTEEN,
                                GROUP_FIFTEEN, CHALCOGEN, HALOGEN, NOBLE_GAS
                                };
        enum class orbitals {ORBITAL_NOTSET, S_ORBITAL, P_ORBITAL, D_ORBITAL, F_ORBITAL};
        enum class metal_status {METAL = 0, METALLOID, NONMETAL};
        Element() = default ;
        Element( int aNumber, int pNumber, groupNames groupnames, metal_status MetalStatus, orbitals Orbital,
                 std::string eName, std::string eSybol) ;
        void displayProperties();

    private:
        groupNames groupNumber = groupNames::HYDROGEN ;
        orbitals orbital = orbitals::ORBITAL_NOTSET ;
        metal_status metalStatus = metal_status::METAL ;
        std::string elementSymbol; 
        std::string elementName;
        int atomicNumber = 0 ;
        int periodNumber = 0 ;
};

Element::Element( int aNumber, int pNumber, groupNames groupnames, metal_status MetalStatus, orbitals Orbital, 
                  std::string eName, std::string eSymbol ) : elementSymbol(eSymbol), elementName(eName)
{
    groupNumber = groupnames;
    metalStatus = MetalStatus;
    orbital = Orbital;
    atomicNumber = aNumber;
    periodNumber = pNumber;
    // elementName = eName;
    // elementSymbol = eSymbol;
}

// ...

std::array< Element, 115 > Elements
{
    {
        {},
        { 1,1, Element::groupNames::HYDROGEN, Element::metal_status::NONMETAL, Element::orbitals::S_ORBITAL, "Hydrogen", "H" },
        // { .... },
        // ...
    }
};

int main()
{
}

http://coliru.stacked-crooked.com/a/3be9e32c3918da8b

Btw, though this has terrible semantics, we won't get any error from the compiler for it (there is nothing wrong with the syntax per se.):
1
2
int foo = foo ;
int bar[2] = { bar[0], bar[1] }; 

Last edited on
Thanks. I actually got this working. I tried the double brace solution. If I remember right, no second set of braces is needed if there is an = operator. Never thought of it in terms of it acting like a struct.

By the way, why don't I have to pass arguments within a class?

Look at my definition for void displayProperties();
I am able to display all properties without passing the arguments for each variable. Why is this?
> By the way, why don't I have to pass arguments within a class?
> I am able to display all properties without passing the arguments for each variable. Why is this?

You are implicitly passing an argument when you call void Element::displayProperties();

Where e is an Element, and we write e.displayProperties() ;,
the address of e provides the implicit argument that is passed to the function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>

struct A
{
    void mem_fun_display() const ;
    void mem_fun_display2() const ;
    int v ;
};

void free_fun_display( const A* This )
{
    // 'This' is the parameter that is explicitly passed to the function
    // 'This' is a pointer which points to the object to be displayed
    std::cout << "free_fun_display() is called to display the object "
               << "at address    " << This << "  A{"
               << This->v // member 'v' of object pointed to by 'This'
               << "}\n" ;
}

void A::mem_fun_display() const
{
    // 'this' is a keyword; used to access a parameter that is inplicitly passed
    // 'this' is a pointer which points to the object to be displayed
    const A* This = this ;
    std::cout << "A::mem_fun_display() is called to display the object "
               << "at address  " << This << "  A{"
               << This->v // member 'v' of object pointed to by 'This'
               << "}\n" ;
}

void A::mem_fun_display2() const
{
    std::cout << "A::mem_fun_display2() is called to display the object "
               << "at address " << this << "  A{"
               << v // this->v (member 'v' of object pointed to by 'this')
               << "}\n" ;
}

int main()
{
    A a {100 } ;

    free_fun_display( &a ) ;
    a.mem_fun_display() ;
    a.mem_fun_display2() ;

    // free_fun_display() ; // ***error: pointer to an object is required
    // A::mem_fun_display() ; // ***error: object is required
}

http://coliru.stacked-crooked.com/a/78ce639496641a8a
Oh, okay. Thanks. That makes perfect sense.
Topic archived. No new replies allowed.