Array accessibility in class environment

Array accessibility, in class environment.
During my book progress, i have little less examples for array/vectors with constructor.

In case if I have Header, Cpp and file with main function, i suggested to initialize array with variables in main file.
Is there a way to initialize it in cpp file and access from cpp file as per below?

Please also advise what are the other options array/vectors accessibility with class objects. Big thanks in advance!

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
#define DATE_H

#include <string>
#include <array>
class Date
{
public:
std::array <std::string, 12> Date; 


Date(int month); 


void OutputDate ();



private:

int month;






}; 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include "Date.h" 

using namespace std;


array Date:: <string, 12> month = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "November", "December"};

Date::Date(int monthX)
: month( monthX )
{


}


void Date::OutputDate()
{
cout << month[1] << endl;
}
 



1
2
3
4
5
6
7
8
9
#include <iostream>
#include "Date.h" 
using namespace std;
int main()
{

Date Obj1(1);
Obj1.OutputDate();
} 
Last edited on
By putting your class' declaration in a header file (.h) and the implementation of that class in a separate source file (.cpp), the class can then be "used" in any source code file (.cpp) of your application, including your "main" source code file – simply by #include'ing the respective header file.

This, of course, means that any public methods and fields of the class can be accessed. Though you should be aware that, unless the field is declared static, then each instance of the class has its own separate field!

Note: A static field is "shared" by all instances of a class.

Also note that static fields should be used with extreme care. It's usually okay for things like constants.

So, maybe you want:

Date.h
1
2
3
4
5
6
7
class Date
{
public:
    static const std::array<std::string, 12> months;

    /* ... */
};

Date.cpp
1
2
3
4
5
#include "Date.h"

const std::array<std::string, 12> Date::months = {
    "January", "February", "March", "April", "May", "June", "July", "August", "September", "November", "December"
};

main.cpp
1
2
3
4
5
6
#include "Date.h"

int main()
{
    std::cout << Date::months[0] << std::endl;
}
Last edited on
How to amend the code?
How to amend the code?

Click the "Edit" button below your post, if that is what you mean...
date.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// date.h
#include <string>
#include <array>

class Date
{
    public:
        // static: shared by all objects of type Date
        // const: we don't want these to be modified
        static const std::array < std::string, 12 > month_names;


    explicit Date( int month );


    // ...



    private:
        int month;
        // ...
};


date.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
// date.cpp
#include "date.h"

const std::array < std::string, 12 > Date::month_names
{ {"January", "February", "March", "April", "May", "June", "July", "August", "September", "November", "December"} } ;

Date::Date( int month ) : month(month)
{
    // validate that month is not out of range
    // throw or correct on error
}

// ... 
Works! Thanks, guys!!!
I will use this as template, but I would love to understand this more deep.
Static and Const together make no sense for me, I will try to figure this out, but now I'm trying to find alternatives:

Is there any another (non-magic library functions or complicated things as inline) option to make my
described case work?

Last edited on
impetus wrote:
Static and Const together make no sense for me
const and static are kind of orthogonal! You can have them solitary as well as combined.


const means that a variable or field does not change. It's initialized once and then its value is fixed.

In fact, the value of a const variable/field could already be predetermined at compile-time.


When it comes to member variables, then static means that the member variable is shared between all the instances (objects) of that class - rather than giving each instance its own separate member variable.

Note: A static variable still is perfectly modifiable – unless declared const.

static has a somewhat different meaning when applied to "global" variables declared outside of a class.


Is there any another (non-magic library functions or complicated things as inline) option to make my described case work?

Not quite sure what you mean?!

All that was discussed in this thread were very fundamental C++ features. No "magic" involved.
Last edited on
You may want to declare your array as having 13 members. We normally deal with months as being 1-12. It's more intuitive than 0-11.
date.h
1
2
3
4
5
class Date
{
public:
    static const std::array<std::string, 13> months;
};

date.cpp
1
2
3
4
5
6
#include "Date.h"

const std::array<std::string, 13> Date::months = {
    /* Note the null string for the 0th element */
    "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "November", "December"
};
Last edited on
Please also advise what are the other options array/vectors accessibility with class objects. Big thanks in advance!

you can overload your class's [] operator to provide access to one container if you want.

you can overload your class's [] operator to provide access to one container if you want.


I'm familiar with overloading a little, but can not guess what exactly do you mean :)
Last edited on
I'm familiar with overloading a little, but can not guess what exactly do you mean :)

For example, you can do:
1
2
3
4
5
6
7
class Date
{
public:
    const std::string& operator[](const size_t n) const;
private:
    static const std::array <std::string, 12> months;
};
1
2
3
4
5
6
7
8
9
10
const std::array<std::string, 13> Date::months = { ... };

const std::string& Date::operator[](const size_t n) const
{
    if (n >= 12)
    {
        throw std::out_of_range("bad index");
    }
    return months[n];
};
1
2
3
4
5
int main()
{
    Date instance; // <-- requires an instance (object)
    std::cout << instance[7] << std::endl;
}


Using a static "getter" method works just as well and should actually be preferred here:
(IMO, there is no reason why you should need an instance to access the static data)
1
2
3
4
5
6
7
class Date
{
public:
    static const std::string& get_month(const size_t n);
private:
    static const std::array <std::string, 12> months;
};
1
2
3
4
5
6
7
8
9
10
const std::array<std::string, 13> Date::months = { ... };

const std::string& Date::get_month(const size_t n)
{
    if (n >= 12)
    {
        throw std::out_of_range("bad index");
    }
    return months[n];
};
1
2
3
4
int main()
{
    std::cout << Date::get_month(7) << std::endl;
}


...and even a non-static "getter" method is possible, but I don't see much reason for this:
1
2
3
4
5
6
7
class Date
{
public:
    const std::string& get_month(const size_t n) const;
private:
    static const std::array <std::string, 12> months;
};
1
2
3
4
5
int main()
{
    Date instance; // <-- requires an instance (object)
    std::cout << instance.get_month(7) << std::endl;
}
Last edited on
^^^ something like that.
the idea is that your object would support array notation.
mything[index] = something; //generic example of the idea
which is the same as
mything.somecontainer[index] = something //exact same as above assuming public member or
mything.setcontainer(index,something) //private member with setter
--- its just another way to grant access or do a 'getter/setter' concept with less typing and clutter.


honestly the number of times this is useful is smaller than you would think. But when your object is wrapping a container to add just a little bit of something special around it... note that generally its a violation of OOP pie-in-the-sky concepts, namely data hiding and protection. Those concepts exist for a reason, but there are times you don't need all that.

Last edited on
Topic archived. No new replies allowed.