2

I have a class contains a private property and a virtual method.

class A
{
  private:
    int var1;
    virtual int foo()
     { return var1;}
 public:
    A(){  var1 = 2; }
};

In my "main" function I have:

 A a;
 cout<<func1(&a);

I want to get the value of var1 and return value of "foo" function in "func1" without changing the class. If I want to solve it I could add set and get methods for var1 but I am not suppose to change the class. How is it possible? Any reference for accessing private methods and properties from outside of the class?

Mahsa
  • 1,502
  • 7
  • 18
  • 40
  • Your `foo` function is private! – Ed Heal Nov 03 '15 at 17:39
  • @Mooing Duck yeah I could do that but I was wondering is there any way to have access to them in the function func1. – Mahsa Nov 03 '15 at 17:42
  • and @Ed Heal yes it is private that makes it difficult! – Mahsa Nov 03 '15 at 17:42
  • You could make func1 a friend of class A. Technically, that entails changing the class but your professor may not think so. – Anon Mail Nov 03 '15 at 17:43
  • 3
    No way without breaking C++ language rules. That's exactly what `private` is used for: you cannot access members from outside. See http://www.gotw.ca/gotw/076.htm – Christian Hackl Nov 03 '15 at 17:44
  • 3
    @AnonMail: I would hope that no "professor" is involved with this rather meaningless exercise. – Christian Hackl Nov 03 '15 at 17:45
  • 2
    @EdHeal It can be used nicely with the NVI idiom, http://www.gotw.ca/publications/mill18.htm. – James Adkison Nov 03 '15 at 17:47
  • 2
    @EdHeal: That's wrong. Private virtual member functions are **best practice** in C++! – Christian Hackl Nov 03 '15 at 17:47
  • 1
    A very similar question here: [Accessing private members](http://stackoverflow.com/questions/726096/accessing-private-members) – Bo Persson Nov 03 '15 at 18:03
  • 1
    cout << 2 works, given the implementation of A – pm100 Nov 03 '15 at 18:17
  • This sounds like an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). What are you really trying to solve? – legalize Nov 03 '15 at 21:00
  • @legalize I have had this question in mind and wanted to know if there is actually a solution to this, I know encapsulation, virtual and private definitions but I came across this problem and I thought based on my knowledge it cannot be solved without writing a friend or another class for it. I wrote another class that inherits from this one, override the foo and solved it. I just wanted to know opinions on this problem and whether I am right or wrong. – Mahsa Nov 03 '15 at 22:53
  • @Rubbic The reason that I ask is because this question comes up all the time in unit testing when attempting to write tests for a class after the fact. The general problem is one of class design instead of "how do I get at that `private` thing?", which is why this sounded like an XY problem. In the context of specific code, there is almost always a better solution than the suggestions that have been made here. – legalize Nov 03 '15 at 23:21

4 Answers4

5

You cannot access private methods from outside the class.

However, the method is virtual it can be overridden by derived classes, even if it's private. When the virtual method is called, the overridden version will be invoked.

Jared Dykstra
  • 3,596
  • 1
  • 13
  • 25
  • Can you provide sample code? If you attempt to invoke the virtual method via a pointer `A`, it won't compile because `A::foo` private. A subclass can define a `foo` method, but it won't be able to access neither `A::foo` nor `A::var1`, both being private to `A`. – user4815162342 Nov 03 '15 at 17:46
  • 2
    How will that allow access to `A::var` or `A::foo()`? – R Sahu Nov 03 '15 at 17:48
  • @user4815162342: The function can make a `class B : public A`, and copy construct it from the `A` passed in, thus bypassing the pointer to base class issue, and that `A::foo()` is private. However, I can't figure out how to access the value of `var1` in any way from `B`. – Mooing Duck Nov 03 '15 at 17:49
  • 1
    @R Sahu, it doesn't allow access to A::var or A::foo(). But it does allow you to re-implement it in your class. @R Sahu suggests using `friend`, but that requires modifying the base class, in which case you can change `private` to `protected` – Jared Dykstra Nov 03 '15 at 17:50
  • 1
    @JaredDykstra: So, in summary, you don't have an answer for the question as posed? – Mooing Duck Nov 03 '15 at 17:51
  • (For those curious, using statements can''t be used to convert private to public: http://coliru.stacked-crooked.com/a/d539da1e84b2b4eb) – Mooing Duck Nov 03 '15 at 17:52
  • 1
    @JaredDykstra What's the point of being able to re-implementing `foo`, the task being to *get the value of var1 and return value of "foo" function*, both being inaccessible to the subclass? – user4815162342 Nov 03 '15 at 17:53
  • @Mooing Duck - The answer to "How can we access to the private virtual method in C++?... without changing the class" is "You cannot" – Jared Dykstra Nov 03 '15 at 17:53
  • 1
    Along with some (public) template function implemented in the base class, allowing this function to be overridden makes well sense. I remember having this specific use case [here](https://github.com/makulik/sttcl/blob/master/sttcl/include/State.h). – πάντα ῥεῖ Nov 03 '15 at 17:56
3

The only way to access the private methods and variables of a class is through a friend declaration -- by making a class or function a friend.

If you are not allowed to modify the class in any way, then you cannot access the private method or variable from func1.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • @R Sahu yes you are right and I know that but the point is I want to figure out a way to access those privates! – Mahsa Nov 03 '15 at 18:02
  • @Rubbic In fact you cannot. The point is, you are able to reimplement them in derived classes. That's the only viable way this class allows to change behaviour. – πάντα ῥεῖ Nov 03 '15 at 18:05
  • @Rubbic, you might be able to find a non-standard way to manipulate pointers and get access to the member variable. I don't know of a standards compliant way to accomplish what you are trying. – R Sahu Nov 03 '15 at 18:05
0

As already mentioned, you can only access private members of a class from within the same class or via a friend function of the class.

Since func is neither a member of the class A nor a friend function of class A, then you cannot call the private function foo from func...unless we make some changes.

Observing that you are passing an address of an A object to func and you wish to call the private function foo, then implementing func as a friend function of the A class should be the obvious choice.

#include<iostream>

class A
{
    public:
        A():var(2){}
        virtual ~A(){}
        friend int func(A const* a){return a->foo();}
    private:
        virtual int foo() const{return this->var;}
        int var;
};

int main()
{
    A a;

    std::cout << func(&a) << std::endl;

    return 0;
}
k170
  • 383
  • 5
  • 18
  • I like your explanation. As mentioned in other answers there is no way to call those private methods inside 'func' and your suggestion is changing the Class A itself. I like the way you phrased it. – Mahsa Nov 05 '15 at 17:58
  • @Rubbic, glad I could help. – k170 Nov 05 '15 at 18:02
-1

In C++ ideology you cannot read or modify private members in others classes - it is named 'encapsulation'.

But, this hack code will success work on all popular compilators:

int& func1(A* a)
{
    struct Hacker  // copy of class A in memory by structure
    {
        int var1;
        virtual void fakeUnused() { }  // need because A have one virtual function too
    };
    Hacker* hacker = reinterpret_cast<Hacker*>(a);
    return hacker->var1;
}

Now, you can read and write A::var1:

A a;
cout << func1(&a) << endl;  // prints '2'

func1(&a) = 3;
cout << func1(&a) << endl;  // prints '3'

But, DONT USE THIS HACK IN REAL CODE! It is very bad practice! Because of this code not complete portable.

Karpuzoff
  • 19
  • 3
  • I don't think it's useful to answer a question with stuff that is intentionally in violation of the language. – legalize Nov 03 '15 at 20:59
  • WoW! This is actually working!!!! But it is violation I think! based on all the discussions it is obvious that there is no solution to this problem in the right way and the only way is this one! – Mahsa Nov 03 '15 at 22:47
  • @legalize Yes, it is violation of C++ rules. And i say it in answer. But, it is once REAL SOLUTION for topic starter. In not enterprise, in scholl this solution will be useful, for present C++ knowledge. – Karpuzoff Nov 04 '15 at 12:07
  • @Rubbic This solution successfully work with llvm, gcc, msvc compilators on x86 and x86-64 architectures. But, if you search portable solutiuon for enterprise code, don't use this. And yes, this method once real solution :) – Karpuzoff Nov 04 '15 at 12:13
  • 1
    While intentionally subverting the language by using unsafe techniques may "work" in the sense that it doesn't crash, it isn't the sort of "trick" we should be recommending on stack overflow as a real answer. This is the sort of thing that people find with google and then add to real systems and cause more problems than they solve. – legalize Nov 04 '15 at 16:04