-2

After getting a lot of help from the internet i finally was able to write the program below, but i have some confusions now. CONFUSION 1: Can anyone explain to me the function of access method.

int access()const
        {
            return n;
        }

CONFUSION 2 : I don't understand the working of the lines below in he program i have written.

int* ptr=(int*)&f1;

Here is the program:

#include<iostream>
using namespace std;
class Factorial
{
    int n;
public:
    Factorial():n(0){}
    int access()const
    {
        return n;
    }
    int Calculate()const;
    void display()const;
};
int Factorial::Calculate()const
{
    int f=1;
    int i=0,j;
    j=access();
    for(i=1;i<=j;i++)
    {
        f=f*i;
    }
    return f;
}
void Factorial::display()const
{
    cout<<"\nFactorial is : "<<Calculate();
}
int main()
{
    const Factorial f1;
    int* ptr=(int*)&f1;
    int n1;
    cout<<"Enter the number whose factorial is to be calculated ";
    cin>>n1;
    *ptr=n1;
    f1.display();
}
  • 1
    Regarding "confusion 1", what about the function confuses you? – Some programmer dude May 18 '21 at 07:27
  • 3
    Regarding "confusion 2", everything regarding `ptr` is wrong and break the rules of C++ (it breaks *strict aliasing* as well as attempting to modify a constant object). Who told you to use something like that? – Some programmer dude May 18 '21 at 07:28
  • Question title does not match question content. No static methods or static objects on sight. – user7860670 May 18 '21 at 07:28
  • There are no static objects or methods here, and modifying a const object has undefined behaviour. – molbdnilo May 18 '21 at 07:28
  • `reinterpret_cast` usage is often wrong. Here too (through a C-cast). – Jarod42 May 18 '21 at 07:30
  • 3
    So you wrote code that you don't understand, and now you're wondering why you wrote it that way? – molbdnilo May 18 '21 at 07:30
  • @Someprogrammerdude Can you not legally cast a pointer to a compund to a pointer to its first element? With structs (or classes with all public) it's certainly possible; does the private part in `Factorial` prevent that? – Peter - Reinstate Monica May 18 '21 at 07:37
  • @Peter-ReinstateMonica Unfortunately the class is not a POD (because it's not [trivial](https://en.cppreference.com/w/cpp/named_req/TrivialType)) so there's no guarantee that the member will actually be first in the object. Also using the pointer breaks strict aliasing. And as mentioned, the object is defined as *constant* which means any attempt to modify it leads to UB. – Some programmer dude May 18 '21 at 07:48
  • 1
    Generally, if you ever feel the need to use a C-style casting (as is done with `(int*)&f1`) you should take that as a sign that you're doing something wrong. – Some programmer dude May 18 '21 at 07:49
  • @Someprogrammerdude Thanks, "trivial" is what I was looking for. – Peter - Reinstate Monica May 18 '21 at 08:01
  • @Someprogrammerdude And at the danger of nitpicking: The cast does not violate strict aliasing: The object pointed to is indeed an int. (It is wrong for the other reasons you mentioned though.) – Peter - Reinstate Monica May 18 '21 at 10:57

1 Answers1

0

A good book on C++ will explain all this to you

(Your question title is not very clear, you ask nothing about "static")

  1. a is a private class member variable ("private:" is implicit if the accessor type is not specified before). I.e. you cannot see it's value outside of the class (unless you are befriended). To see the value of a you call the member function access that returns the value it copies from a. (Note it is marked const which means it doesn't modify the class object).

  2. int* ptr=(int*)&f1; consists of several parts. first the address of object f1 is taken using the &-operator. Then using a C-style cast the result is converted to an int pointer. That value is assigned to ptr, which is declared as an int pointer. C-style casting is not the way you should do it in C++. It is particularly bad in this code as it's just wrong to convert from Factorial* to int*: it's not an int. Furthermore, as ptr is not used, the whole line is redundant.

JHBonarius
  • 10,824
  • 3
  • 22
  • 41
  • 1
    If `Factorial` were a `struct`, the cast would be legal though, would't it? The object there *is* an int. (I suppose that `n` is private makes this illegal, allowing compilers to re-order the members by accessability; but in all reality I think none of them does that, and since `n` is the only member to begin with it can reorder all it wants, it'll always be first.) – Peter - Reinstate Monica May 18 '21 at 07:38
  • @Peter-ReinstateMonica is that really legal (I'm no language lawyer)? I mean, that would be making assumptions that could easily break with any future changes (i.e. adding dynamic polymorphism, more objects etc.) Wouldn't this be UB? – JHBonarius May 18 '21 at 07:42
  • 1
    Oh yes, non-virtual and perhaps other restrictions (probably no multiple inheritance). Basically PODs (unsure myself what exactly is required). But basically `struct { int i; char c; } s; int *p = (int *)&s;` is allowed, iirc. – Peter - Reinstate Monica May 18 '21 at 07:48
  • The cast sounds like bad practice in any case. Especially given that the question is asked by a beginner, I'd strongly say that we should recommend usage of `std::dynamic_cast` (and no cast in this case), even if it would be proper defined behaviour. – Aziuth May 18 '21 at 07:56
  • @Aziuth Of course it is terrible (and, as SomeProgrammerDude correctly remarked, illegal because `Factorial` is not a trivial type (due to its user defined constructor), and because `f1` is const). – Peter - Reinstate Monica May 18 '21 at 08:09