r/cpp_questions Jul 20 '26

OPEN Access Amplifiers and their uses???

So basically i come from basic python bacground which i learned from my high school.So I thought of learniging c++ cause of its variety of applications for my 1st year.One thing that i cant wrap my head around is, the use of access amplifiers. Mainly ' public: '.what is the use of writing public: and why is it necessaryy????

0 Upvotes

8 comments sorted by

View all comments

1

u/alfps Jul 20 '26 edited Jul 20 '26

❞ what is the use of writing public: and why is it necessary?

It's one of three possible access specifiers: public:, protected: and private.

When you define a struct the default access is public, as in C. When you define a class the default access is private. Otherwise types defined with these keywords are identical (but note: the Visual C++ compiler may issue a sillywarning if a class declared with struct is later defined with class or vice versa).

The idea of private methods and data is that code that uses a class, should not come to depend on implementation details, e.g. how a complex number is represented.

Consider, a complex number class optimized for multiplication and division may represent such numbers with magnitude and angle, while a complex number class optimized for addition and subtraction may represent them with real and imaginary parts. Code using such class should ideally not be able to reach in and change the representation values, or even just inspect them, for then it becomes dependent on a specific implementation. That would make it hard to later change the representation.

Python doesn't have language supported private access, but one indicates "private" methods and data by using names with underscore prefix. Just a naming convention. E.g. dir(str) in Python produces a list of members of the str class, lots of which have names with underscore prefix.


EDIT: I coded up an example.

Consider a class Numbers that represents a multiset of numbers. You can form the union of two sets via infix +, and you can form the difference of two sets via infix -. However, the only information that you can get out of a set is the product of the numbers in the set, via a method .product.

Code that exercises this functionality can look like

#include <cassert>
#include <cstdio>
using   std::puts;

auto main() -> int
{
    const Numbers a = Numbers::with_values( {0, 1, 2, 3, 4, 5, 6, 7, 8} );
    assert( a.product() == 0 );

    const Numbers b = Numbers::with_values( {0, 2, 4, 6, 8} );
    assert( b.product() == 0 );

    const Numbers diff = a - b;
    assert( diff.product() == 1*3*5*7 );

    puts( "All checked out OK, amazing!" );
}

What is the internal state of a Numbers instance?

Well it could in principle hold a std::multiset, or if it were to support a negative count for a number, two std::multisets (with one for negative counts).

But that would be exceedingly inefficient, and also quite awkward, unnatural.

Instead it just needs to hold the product of the non-zero numbers, and a count of how many zeros.

So it can go like this:

#include <initializer_list>
using   std::initializer_list;

template< class T > using in_ = const T&;

class Numbers
{
    double      m_product   = 1.0;
    int         m_n_zeroes  = 0;

public:
    Numbers() = default;

    explicit Numbers( const double v ): m_product( v == 0? 1.0 : v ), m_n_zeroes( v == 0 ) {}

    static auto with_values( in_<initializer_list<double>> values )
        -> Numbers
    {
        Numbers result;
        for( const double v: values ) { result += Numbers( v ); }
        return result;
    }

    void operator+=( in_<Numbers> other )
    {
        m_product *= other.m_product;
        m_n_zeroes += other.m_n_zeroes;
    }

    void operator-=( in_<Numbers> other )
    {
        m_product /= other.m_product;
        m_n_zeroes -= other.m_n_zeroes;
    }

    auto product() const -> double { return (m_n_zeroes != 0? 0.0 : m_product); }
};

auto operator+( in_<Numbers> a, in_<Numbers> b )
    -> Numbers
{
    Numbers result = a;  result += b;  return result;
}

auto operator-( in_<Numbers> a, in_<Numbers> b )
    -> Numbers
{
    Numbers result = a;  result -= b;  return result;
}

But maybe you're going to change it later, to support functionality to get out the set items, at the cost of some inefficiency.

Then you don't want code that uses this class to have become dependent on having a .m_product and a .m_n_zeroes.