Is the following code legal in C++. Accessing a friend class member public method? I know this sounds confusing, and the best way to show it is in code. I was wondering if the TestClassC::Method() is valid in the code below?
I've compiled (g++) and it works, however, I run into a situation, where it produces a segmentation fault on other machine/distros at TestClassC::Method(). Which is making me wonder if this->classA_Ptr->classB.Method(); is legal in C++.
#include <iostream>
using namespace std;
class TestClassB
{
public:
TestClassB(void){};
~TestClassB(void){};
void Method(void){
cout << "Hello Again" << endl;
}
};
class TestClassC; //Forward Declaration
class TestClassA
{
friend class TestClassC;
public:
TestClassA(void){};
~TestClassA(void){};
private:
TestClassB classB;
};
class TestClassC
{
public:
TestClassC(TestClassA* a_Ptr){
this->classA_Ptr = a_Ptr;
}
~TestClassC(void){};
void Method(void){
//Is this Valid/Legal ???
this->classA_Ptr->classB.Method();
}
private:
TestClassA* classA_Ptr;
};
int main()
{
cout << "Hello world!" << endl;
TestClassA testClassA;
TestClassC classC(&testClassA);
classC.Method();
return 0;
}
The public/private/protected accessor modifiers are enforced at compile-time, not at runtime. The SEGFAULT is a runtime error, not a compile-time error. So, in the future, if you get a SEGFAULT, you can be sure that it is not related to the level of access. It sounds like your confusion is based on whether the access modifiers are applied directly, indirectly, transitively, etc. The access modifiers work in the most simple and straight-forward way: they apply only directly, to the functions or variables that have been declared in that class and control access through the given class to those items. Once you have access to such an item, further access is determined purely by that item's own access modifiers.
A SEGFAULT is typically indicative of an illegal memory access. If you experience SEGFAULTS, look at where you dereference pointers (whenever you have *X or X->Y). Common causes of SEGFAULTS include dereferencing NULL, off-by-one array access, and using an object through a pointer where the object in question has already been deleted by going out of scope.
Yes. The friend specification gives TestClassC access to any protected or private members of TestClassA. So that means it gets access to the classB member. After that, normal rules apply to what TestClassC can do with that member. And since Method() is public TestClassC is allowed to call it, just as if it had gotten ahold of a TestClassB instance through any other means.
Regarding the seg fault:
Public/protected/private/friend are all compile-time restrictions. They should have no affect on the operation of the code at runtime.
Is it this exact code that seg faults? Or is it just something similar in concept? If it's not the exact same code, then have you verified that all the pointers are actually valid in the problematic code?
Calling public methods of any class is valid/legal as long as the class is unambiguously accessible, and we have a valid object expression to access it. In fact that's why it was made public in the first place. Your code looks to be fine to me.
Related
I discovered that next weird code compiles and runs (on VS 2019):
#include <iostream>
class Test
{
private:
struct Priv
{
int a;
};
public:
static Priv WeirdFunc() {return {42};};
};
int main()
{
auto val = Test::WeirdFunc();
std::cout << val.a;
}
Output is 42, no problems here.
The issue I see is that auto keyword allows us to access private structure "Priv".
If I try to replace auto with Test::Priv I get compile error, as expected.
From the articles on the internet I found out that you can have to use auto for lambdas, but this case was never mentioned.
Also, if I try to output "Test::WeirdFunc().a" it also works
So my questions are:
Is it expected behaviour for auto to let us access private structures/classes?
Is it allowed to declare public function that returns private structure?
Is it expected behaviour that we can access private structures/classes if it's return value of function (e.g. "Test::WeirdFunc().a")?
All of that is obviously terrible code style, but I'm curious about whether it's valid c++ code or not
The result of Test::WeirdFunc() is a Priv. This is also the auto-deducted type of val. The auto keyword removes the necessity to name the type of val to be Priv and therefore, the compiler does not complain. As a result, val is of (unmentioned) type Priv and has a public member a, that can be accessed freely.
So the answers to all your questions is: Yes, (as long as you don't "mention" the name of the nested class).
See also: cpp reference on nested classes
So my questions are:
Is it expected behaviour for auto to let us access private structures/classes?
Yes.
Is it allowed to declare public function that returns private structure?
Yes.
Is it expected behaviour that we can access private structures/classes if it's return value of function (e.g. Test::WeirdFunc().a)?
Yes.
All of that is obviously terrible code style, ...
No, not necessarily. Think about e.g. a container class, which defines iterator classes as internal nested types:
class Container {
class iterator {
public:
iterator operator++();
iterator operator++(int);
};
public:
iterator begin();
iterator end();
};
This allows to access the iterator's instances and operations via auto, but not to directly create instances from outside the class.
You have a public interface which exposes a type by means of the type of return value of the public interface. This essentially means your API design exposes private details of the class, and this is not an issue of the C++ language features but of the API design. Note that this doesn't just apply for auto:
using A = decltype(Test::WeirdFunc()); // A is Test::Priv.
A a{}; // well-formed.
It's valid, and here's why:
Access specifiers control access to names.
So, you have no access to the name Priv, but that doesn't mean you have no access to the type it's referring to. And there are other ways to "get to it", such as by using auto.
This is not as crazy as you might think. After all, you can't do any damage with it: if you don't want public things returning instances of "private types" (which aren't, really, but that's fine) then simply don't do that thing.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
Are private non static variable/methods accessible in static function? If yes,
then what is the use of "Private" access modifier?. Please go through the below code.
// Testclassheader.h file
class TestClass{
private:
int TestVariable; //Private Variable
int TestFunction(); //Private Method
public:
static void TeststaticFn(); //Static Method
};
void TestClass::TeststaticFn()
{
TestClass TestObj;
TestObj.TestVariable = 10; // Compiles perfectly
TestObj.TestFunction(); //Compiles Perfectly
}
// Another Class
//#include "Testclassheader.h"
class AnotherClass{
public:
int DummyFunc();
};
int AnotherClass::DummyFunc()
{
TestClass AnotherObj;
AnotherObj.TestVariable = 15; //error: 'TestVariable' is a private member of 'TestClass'
AnotherObj.TestFunction(); //error: 'TestFunction' is a private member of 'TestClass'
}
I tried the above code in Visual studio 12. Can anyone explain why private variable/methods are accessible in static method( which actually it should not)?
All functions of a given class have access to of that class's private members through any instance. You seem to think that private limit access to member functions of that particular instance, which is incorrect.
class foo
{
private:
int bar;
// access of the function doesn't matter, but let's use public
public:
// the only case you thought was legal:
void baz()
{
bar = 1;
}
// but this is perfectly legal
void qux(foo otherFoo)
{
otherFoo.bar = 1;
}
// also legal, as you discovered.
static void quux(foo iPittyTheFoo)
{
iPittyTheFoo.bar = 1;
}
};
class someOtherClass
{
// no function here (static or otherwise) has access to baz.
// UNLESS you "friend someOtherClass" inside class foo. Whether or not
// "friend" is ever a good idea is a matter of some debate.
};
void someGlobalFunction()
{
// Also cannot access bar.
Foo a;
a.bar = 1; // boom
}
// nope. Still cannot access bar.
foo b;
someOtherClass instance(b.bar); // boom
Also, "// throws error" is misleading. "Throw" exclusively refers to exception handling, not compile time errors. Compiler errors, linker errors, and runtime errors are each quite different and require different kinds of problem solving to deal with. When asking for help from someone not looking at the actual error output, you need to specify which it is. Just copy-paste-ing the error itself is generally a good idea, then we all have the same information.
In general, I suspect you've misunderstood the purpose of public:, protected:, and private:. We all had to learn it at some point.
In C++, public functions/methods and variables/members (different people use different terms) represent a class's "interface". These are what everything outside that class is allowed to use. What goes on behind that interface is none of their business (at least in theory).
protected functions and variables are available to classes that inherit from that class. "Your version of this class may be customized in these ways".
private functions and variables are no one else's concern. No touchy. As programs change, implementation details within a given class can vary wildly. The initial implementation of a class might (shudder) return a hardcoded value:
class X
{
...
private:
int Y() { return 1; }
};
Later versions of that same function might look up a value in a database, read from a file, whatever. "Which database?" Okay, now we need a parameter...
int Y(WhichDb thisOne) { return thisOne.lookupY(); }
So everywhere that was calling Y now needs to pass in a WhichDb (which should probably be a const reference, but that's a whole different topic). By changing the "function signature" of Y, we have broken all the code that called Y. In other words, all existing calls to Y are now compiler errors, because they don't pass in a WhichDb. In one sense, public/protected/private define just how much code a given change will affect/break.
Private? Just that class. No problem, I'm responsible for that class (because I can change it's header), so fixing that is no problem.
Protected? That class, plus everything that inherits from it. This could easily Break Someone Else's Code, which is generally bad. Breaking code you're not responsible for is a great way to lose customers.
Public? Anyone, anywhere could have called that function. "Breaking changes" to public interfaces are to be avoided.
So maybe your class is only ever used inside you company, in your department, by you. Public changes at that point are no big deal. On the other hand, Some Popular Library really cannot do that. I mean... they COULD, but they'd probably piss off lots of folks.
There are ways to change your public interface without breaking existing code. You can add new functions, you can add new parameters to existing functions THAT HAVE DEFAULTS: void foo(int bar = 2);. People who called foo() will still compile (and hopefully will still get the same behavior they depended on), but now people can call foo(3) to get new behavior.
Are private non static variable/methods accessible in static function?
Yes, private non static variable/methods are accessible by a static function that is part of the self-same class.
If yes, then what is the use of "Private" access modifier?
It prevents other classes from accessing the private class members and private instance members of the class.
Can anyone explain why private variable/methods are accessible in static method?
Because all the parts of a class are part of the class.
which actually [private variable/methods] should not [be accessible to static methods of the same class])?
That is incorrect.
i know that Members of the class can only be accessed indirectly via set and get-methods. What is the output of the following C++ program? Why is this possible? could someone Explain to me why this is a bad programming style?
#include <iostream>
using std::cout;
using std::endl;
class Test
{
private:
int N;
public:
void setN(int N_in) { N = N_in; };
int getN(){ return N; };
int* getptrN(){ return &N; };
};
int main()
{
Test A;
A.setN(5);
int* ptr = A.getptrN();
cout << A.getN() << endl;
*ptr = 10;
cout << ptr << endl;
cout << A.getN() << endl;
return 0;
}
The public, protected, and private access specifiers apply to names of members. They let you specify which data and functions are available to users of a class by name. If at runtime you grant access to a variable or function through some other means, such as by pointer or reference, then the compile-time access specifiers are no longer at play.
The basic idea of encapsulation is that you want objects to represent values in the problem you’re trying to solve, and you want those values to always be meaningful. You restrict which states an object can have, so that the object can only ever represent meaningful states.
For example, it’s not meaningful for a length to be negative, so a hypothetical setLength member function should never succeed when given a negative argument value.
By granting unrestricted access to a member of an object, you allow it to be modified in ways that don’t necessarily produce a valid state, which can make your program behave incorrectly. If x assumes that its length will only ever be non-negative, but you say *x.getPtrLength() = -1;, then all bets are off.
The public , private try to bring the concept of encapsulation to our codes. This concept helps to separate what that is happening inside of a class to the outside world. This does NOT mean that you can't access to memory space of your objects. Because you have created an instance of the Test object you can access to it; you just need the address of inside variables (which you have provided by return &N).
Not sure I completely understand what you're asking (what exactly is the problem you see with the code), but you need to refresh your memory on public: and private:.
This is another, "My code isn't working and i don't know why, " question i'm afraid. I just don't have enough knowledge of the stl to know why std::map::insert would throw an exception. If you know what cases it throws an exception, you can probably skip this wall of text and just answer. If you just desperately need some background on the issue, then have at it. I'll post my code and explain what is done, and i would be very grateful if all you with a better knowledge of the stl could explain what could be wrong with my call to insert.
I wrote an object awhile ago that i use occasionally as my go to factory object. It's main purpose is basically to take a string and store both the string and a "create new object function" pointer, so that in the end, you can call a function, pass a string, and if there is a valid registration for it, it returns a new instance of a derived object. Less talk, more code, here's what i got:
factory.h
#ifndef FACTORY_H
#define FACTORY_H
// library tools
#include <map>
#include <string>
// Simplified registration macros
#define DECLARE_DERIVED(T, base) static Factory<base>::DerivedRegister<T> reg;
#define DEFINE_DERIVED(T, base, s) Factory<base>::DerivedRegister<T> T::reg(s);
template<class base>
class Factory
{
protected:
template<class T>
static base * createT() { return new T;}
public:
typedef std::map<std::string, base*(*)()> map_type;
virtual ~Factory(){ }
static base * createInstance(const std::string & s)
{
if(!m_Map.count(s))
return nullptr;
std::map<std::string, base*(*)()>::iterator it = m_Map.find(s);
return it->second();
}
template <class T>
struct DerivedRegister;
protected:
static map_type m_Map;
};
template<class base>
template<class T>
struct Factory<base>::DerivedRegister : public Factory<base>
{
DerivedRegister(std::string const & s)
{
m_Map.insert(std::pair<std::string, base*(*)()>(s, &createT<T>));
}
};
#endif
here's a better explanation of what it does real quick. Let's say you have a base class, class A . and then you have any number of derived classes. I make a factory object somewhere templated to A, and then either create a derived register object manually, or use the macro at the top within the derived classes declaration to create a static registry object. Then you define it in the implementation and call it's constructor, passing in a string to be used to identify the object. using the factory member createInstance you can pass in a string identifier and have a derived object returned, pointed to by an A *.
example:
A.h
class A
{
};
A.cpp
// the map for this factory template has to be defined somewhere, as it is static
Factory<A>::map_type Factory<A>::m_Map;
b.h
#include <A.h>
class B : public A
{
// anywhere in declaration of derived B
DECLARE_DERIVED(A, B)
};
b.cpp
// just somewhere in cpp file
DEFINE_DERIVED(A, B, "B")
main.cpp
int main()
{
A * ptr;
Factory<A> factory;
ptr = factory.createInstance("B");
}
This object has worked for me in the past, mostly without a hitch. Now i'm doing a project a little more complicated. I've taken a liking to the data organization/ api design involved with game engines, and i'm just trying to implement a solution of cataloging, (but not instantiated) shaders, so that you have a whole list of the shaders you've programmed, but they will not be instantiated at run-time unless needed. That aside, this question actually has nothing to do with d3d11, or at least i hope not.
So here is what's going on. I have an object that represents a graphics-shader abstract class. All the shaders you wish to write must derive from this object. The you derive from and implement it's functions differently for all your different shaders.
let's call the base object "SYNC::D3D11Shader" in namespace sync and the derived shaders "ColorShader" "LightShader" and "TextureShader". Since i do not simply want to make an std::map of instances of these shaders within the rendering object, i make a factory within the rendering object like this.
D3D11Renderer.h
class D3D11Renderer
{
// many other members...
Factory<D3D11Shader> m_ShaderFactory;
// many other member...
};
D3D11Renderer.cpp
// define this templated classes map or you'll get undefined errors
Factory<SYNC::D3D11Shader>::map_type Factory<SYNC::D3D11Shader>::m_Map;
and then in the ColorShader i use the macros like so
D3D11ColorShader.h
class D3D11ColorShader : public SYNC::D3D11Shader
{
// ...lotsa members
DECLARE_DERIVED(D3D11ColorShader, SYNC::D3D11Shader)
// lotsa member...
};
D3D11ColorShader.cpp
// define the registery object with it's key here
DEFINE_DERIVED(D3D11ColorShader, SYNC::D3D11Shader, "ColorShader")
this all compiles fine, and where it throws it's exception is where i first call the registryObjects constructor in D3D11ColorShader.cpp, spefically at the insert call. the exception error is this:
Unhandled exception at 0x772315de in Syncopate.exe: 0xC0000005: Access
violation reading location 0x00000004.
So in reality, the question boils down to, when does std::map::insert throw an exception and why. I just knew everyone would be asking for some background on what i'm doing. Low and behold, a giant wall of text has appeared! All i really need is a hunch.
also should i or should i not tag d3d11, because the question doesn't really pertain to it?
Here's a problem:
std::map<std::string, base*(*)()>::iterator it = m_Map.find(s);
return it->second();
if the call to find fails (i,e. it can't find 's' in the map), then it will return m_Map.end(). Dereferencing that is a no-no.
My guess would be that this is due to the order of initialization of static variables. There is no way to control this order. So you are not guaranteed that your initialization:
Factory<A>::map_type Factory<A>::m_Map;
gets called before this initialization:
DEFINE_DERIVED(A, B, "B")
In this case the latter statement must be getting initialized first and so you map has not been allocated.
An alternative design pattern would control the initialization of the singleton factories. If you have an explicit Initialize function on each which creates the factory object then you can call this at the start of your main. E.g.
Factory.h
class Factory {
private:
static Factory* instance_;
public:
static Initialize(){instance_=new Factory;}
Factory* instance(){return instance_;}
}
Factory.cpp
static Factory* Factory::instance_ = NULL;
If you have a lot of factories you will probably want a single initialize function that initializes them all, and you will have to remember to add in the new factories as you create them.
Okay, i have actually been laboring over this error for about a day, and only now do i realize what is wrong.
problem 1:
the derived shaders header was never actually included anywhere throughout the project, and despite the fact that it never needs to be directly instantiated, it still has to be included somewhere so it can be linked and included in build.
problem 2:
interesting enough, just like combinatorial said, the initialization order was not done one after the other, but then looking over my old code, it seemed to initialize correctly before. what the difference here was, i put the factory of the derived objects within a different object then the base class. what i used to do was declare a static function and static factory within the base class so that you could instantiate any of it's registered derived classes from the base class itself. When the factory is included within the base class instead, and instantiation is done through a static function, the initialization order of all the statics seems to be constently in order ( not sure if this is always true). It runs fine now after changing this.
so now, my answer, you can get operating system exceptions like this for trying to use references to objects that were never actually included anywhere in your project. I don't have a very good knowledge of compilers or linkers to tell you why it seemed to compile fine, despite this object never being included. If someone wants to extend my answer, please.
I use MSVC++ 2010 express if that pertains to this predicament.
In the below code, there are two "equivalent" calls to std::for_each using boost:bind expressions. The indicated line compiles, the indicated failing line fails. The best explanation I can find in the standard amounts to "because we said so". I'm looking for "why the standard indicates this behavior". My suppositions are below.
My question is simply: Why does the indicated line compile and the equivalent following line fail to compile (and I don't want because "the standard says so", I already know that - I will not accept any answers that give this as an explanation; I'd like an explanation as to why the standard says so).
Notes: Although I use boost, boost is irrelevant to this question, and the error in various formats has been reproduced using g++ 4.1.* and VC7.1.
#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <algorithm>
class Base
{
protected:
void foo(int i)
{ std::cout << "Base: " << i << std::endl; }
};
struct Derived : public Base
{
Derived()
{
data[0] = 5;
data[1] = 6;
data[2] = 7;
}
void test()
{
// Compiles
std::for_each(data.begin(), data.end(),
boost::bind(&Derived::foo, this,
boost::bind(&std::map<int, int>::value_type::second, _1)));
// Fails to compile - why?
std::for_each(data.begin(), data.end(),
boost::bind(&Base::foo, this,
boost::bind(&std::map<int, int>::value_type::second, _1)));
}
std::map<int, int> data;
};
int main(int, const char**)
{
Derived().test();
return 0;
}
The indicated line fails with this error:
main.C: In member function 'void Derived::test()':
main.C:9: error: 'void Base::foo(int)' is protected
main.C:31: error: within this context
As noted, the supposedly equivalent statement above compiles cleanly (and if the offending statement is commented out, runs with the expected result of printing “5”, “6”, “7” on separate lines).
While searching for an explanation, I came across 11.5.1 in the standard (specifically, I’m looking at the 2006-11-06 draft):
An additional access check beyond
those described earlier in clause 11
is applied when a non-static data
member or nonstatic member function is
a protected member of its naming class
(11.2)105) As described earlier,
access to a protected member is
granted because the reference occurs
in a friend or member of some class C.
If the access is to form a pointer to
member (5.3.1), the
nested-name-specifier shall name C or
a class derived from C. All other
accesses involve a (possibly implicit)
object expression (5.2.5). In this
case, the class of the object
expression shall be C or a class
derived from C.
After reading this, it became evidently why the second statement failed while the first succeeded, but then the question came up: What is the rationale for this?
My initial thought was that the compiler was expanding the boost::bind templates, discovering that Base::foo was protected and kicking it out because boost::bind<…> was not a friend. But, the more I thought about this explanation, the less it made sense, because if I recall correctly, as soon as you take the pointer to a member (assuming you initially are within access control of the member), all access control information is lost (i.e. I could define a function that returns an arbitrary pointer to a member that alternately returns a public, protected or private member depending on some input and the returner would be none the wiser).
More I thought about it, and the only plausible explanation I could come up with why it should make a difference was in the case of multiple inheritance. Specifically, that depending on the class layout, the member pointer when calculated from Base would be different than that calculated from Derived.
It's all about "context". In the first call the context of the call is Derived which has access to the protected members of Base and hence is allowed to take addresses of them. In the second the context is "outside of" Derived and hence outside of Base so the protected member access is not allowed.
Actually, this seems logical. Inheritance gives you access to Derived::foo and not to Base::foo. Let me illustrate with a code example:
struct Derived : public Base
{
void callPrivateMethod(Base &b)
{
// this should obviously fail
b.foo(5);
// pointer-to-member call should also fail
void (Base::*pBaseFoo) (int) = &Base::foo; // the same error as yours here
(b.*pBaseFoo)(5);
}
};
The reason for this restriction is enforcement of access control across different classes that share a common base.
This is reinforced by notes in Core Language Defects Report defect #385, the relevant part copied here for reference:
[...] the reason we have this rule is that C's use of inherited protected members might be different from their use in a sibling class, say D. Thus members and friends of C can only use B::p in a manner consistent with C's usage, i.e., in C or derived-from-C objects.
As an example of something this rule prevents:
class B {
protected:
void p() { };
};
class C : public B {
public:
typedef void (B::*fn_t)();
fn_t get_p() {
return &B::p; // compilation error here, B::p is protected
}
};
class D : public B { };
int main() {
C c;
C::fn_t pbp = c.get_p();
B * pb = new D();
(pb->*pbp)();
}
The protected status of D::p is something we want the compiler to enforce, but if the above compiled that would not be the case.