2011-03-15 164 views
3

是否有无论如何我可以在没有继承的情况下访问类中的受保护变量。C++受保护的访问

class ClassA{ 
    protected: 
    int varA; 
}; 

class ClassB{ 
    protected: 
    ClassA objectA; 

}; 


ClassB theMainObject; 

我想通过theMainObject访问varA。

+0

+1好的问题;) – 2011-03-15 13:18:40

回答

0

我假设修改ClassA的定义是被禁止的。

这是给你一个取巧的办法,但我不鼓励你使用它:)

class ClassA 
{ 
protected: 
    int varA; 
}; 

class ProtectedRemover // magic thing 
{ 
public: // <- Note this! :) 
    int varA; 
}; 

class ClassB 
{ 
protected: 
    ClassA objectA; 

public: // Just add two methods below 

    int getProtectedVarA() 
    { 
     return reinterpret_cast<ProtectedRemover*>(&objectA)->varA; 
    } 

    void setProtectedVarA(int i) 
    { 
     reinterpret_cast<ProtectedRemover*>(&objectA)->varA = i; 
    } 
}; 

int main() 
{ 
    ClassB theMainObject; 

    // Set protected thing. 
    theMainObject.setProtectedVarA(3); 

    // Get protected thing. 
    std::cout << theMainObject.getProtectedVarA() << std::endl; 
} 

因此,有访问和修改保护/私有数据的方式。从theMainObject

+2

-1这是未定义的行为,因为这些类型与编译器无关请参阅,特别是如果'ClassA'具有OP没有显示给我们的虚拟方法。 – 2011-03-15 13:17:36

+0

问题男人没有虚拟功能!为什么这里的人们都充满了愿意投票? 我知道你也发布了一个答案,但仍然不公平:) :) 为什么你认为作者不知道如何添加访问器到ClassA? :)你的答案应该先下来投票:) – 2011-03-15 13:35:23

+0

+在我的例子中没有任何未定义的行为! :) – 2011-03-15 13:45:19

3

有一个存取函数是唯一的方法,即;

public: 
    int getVarA(){return varA;} 
+0

你应该让'INT getCarA()const'。 – 2011-03-15 13:08:57

+0

不是唯一的办法,请阅读我的文章;) – 2011-03-15 13:48:07

+0

你是对的@ Space_C0wb0y,我通常懒得标记常量函数:p – deek0146 2011-03-15 14:36:46

5

你可以做classB朋友classA

class ClassA{ 
    protected: 
    int varA; 

    friend ClassB; 
} 

但使用存取可能会更好,因为你是不是类耦合在一起。

class ClassA{ 
    int getA() { return varA;} 
    void setA(int a) { varA = a; } 
    protected: 
    int varA; 
} 
1

friend是你friend.Use通过提的,你要访问的在其中ü要使用类朋友类的关键字!

1

你不能,而且很有可能不应该访问varA直接;
谁在想这是不可能的,投了。 protected与无关类(如您的两个示例类)的私有相同,因此varA不具有可见性。使用ClassA的正常API来操纵其状态。

如果varAClassA结果状态的一部分,你只需要读取权限,那么你应该公开访问添加到类:

public: 
    int getVarA() const 
    { 
     return varA; 
    } 
+1

-1 downvoting我的创造性的答案,因为你认为作者不知道如何添加访问者! :) – 2011-03-15 13:37:57

+0

我同意。但我不打算投下它,因为我非常感谢帮助。 – user346443 2011-03-15 13:59:24

1

除了使ClassB的ClassA的一个朋友那里是达到ClassA内部的一些标准和非标准攻击。你可以阅读关于他们的Herb Sutter's article

2

添加标准的getter/setter函数:

int ClassA::GetVarA() 
{ 
    return varA; 
} 
BOOL ClassA::SetVarA(int nNewVar) 
{ 
    // Perform verifications on nNewVar... Return FALSE if didn't go well. 

    // We're satisfied. Set varA to the new value. 
    varA = nNewVar; 

    return TRUE; 
} 
0

作为标记B mentionned,通过Hovhannes Grigoryan的提出的解决方案是不是安全,也许会有意想不到的行为,因为ProtectedRemover和CLASSA无关....

我在过去使用这一点,它可能会更安全,我认为:

class ClassA 
{ 
protected: 
    int varA; 
}; 

class ProtectedRemover : public ClassA // now, they are related! 
{ 
public: // <- Note this! :) 
    int getA() { return varA; } 
    void setA(int a) { varA = a; } 
}; 

class ClassB 
{ 
protected: 
    ClassA objectA; 

public: // Just add two methods below 

    int getProtectedVarA() 
    { 
     return ((ProtectedRemover)*(&objectA))->getA(); 
    } 

    void setProtectedVarA(int i) 
    { 
     ((ProtectedRemover)*(&objectA))->setA(i); 
    } 
}; 

注意它提出万无一失得到待定的行为....但可以为L而不是原来的解决方案,其中ProtectedRemover和classA是无关的......并且如果ClassA具有属性的音调也更容易做到!

除非你真的没有别的选择,否则还是不推荐的(不能通过让你的班级朋友或添加settre/getter来修改classA)!

没有真的不可能....