"传统的"C++类(只是一些随机声明)可能类似于以下内容:
class Foo
{
public:
Foo();
explicit Foo(const std::string&);
~Foo();
enum FooState
{
Idle, Busy, Unknown
};
FooState GetState() const;
bool GetBar() const;
void SetBaz(int);
private:
struct FooPartialImpl;
void HelperFunction1();
void HelperFunction2();
void HelperFunction3();
FooPartialImpl* m_impl; // smart ptr
FooState m_state;
bool m_bar;
int m_baz;
};
Run Code Online (Sandbox Code Playgroud)
如果原始程序员没有整齐地组织他的"访问区域",我总是发现这种类型的访问级别规范很难并且难以遵循.
看一下Java/C#风格的相同代码片段,我们得到:
class Foo
{
public: Foo();
public: explicit Foo(const std::string&);
public: ~Foo();
public: enum FooState
{
Idle, Busy, Unknown
};
public: FooState GetState() const;
public: bool GetBar() const;
public: void SetBaz(int);
private: struct …Run Code Online (Sandbox Code Playgroud) 访问说明符protected和internal protectedC#之间有什么区别?
在Code Complete中的"Good Encapsulation"部分中,建议隐藏私有实现细节.C++中给出了一个例子.这个想法基本上是将接口与实现完全分开,即使在类级别也是如此.
class Employee {
public:
...
Employee( ... );
...
FullName GetName() const;
String GetAddress() const;
private:
EmployeeImplementation *m_implementation;
};
Run Code Online (Sandbox Code Playgroud)
这真的很好用吗?这不仅效率低下(这会带来什么样的性能损失?),但Code Complete("管理复杂性")的整个座右铭似乎已经被逆转 - 这不会增加复杂性吗?
在Ruby类定义中声明private/ 实际发生了什么protected?它们不是关键字,因此这意味着它们必须是方法调用,但我无法找到它们的定义位置.它们似乎没有记录.声明private/ protected方法的两种不同方式(如下所示)是否以不同方式实现?(第二种方式显然是方法调用,但这在第一种方式中并不那么明显.)
class Foo
private
def i_am_private; end
def so_am_i; end
end
class Foo
def i_am_private; end
def so_am_i; end
private :i_am_private, :so_am_i
end
Run Code Online (Sandbox Code Playgroud) 在将该对象注册到另一个对象后,我需要将一些实例方法设为私有.
我不想冻结对象,因为它必须保持可编辑状态,但功能较少.而且我不想取消这些方法,因为它们是在内部使用的.
我需要的是:
class MyClass
def my_method
puts "Hello"
end
end
a = MyClass.new
b = MyClass.new
a.my_method #=> "Hello"
a.private_instance_method(:my_method)
a.my_method #=> NoMethodError
b.my_method #=> "Hello"
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
class A
private
def foo
puts :foo
end
public
def bar
puts :bar
end
private
def zim
puts :zim
end
protected
def dib
puts :dib
end
end
Run Code Online (Sandbox Code Playgroud)
a = A.new
Run Code Online (Sandbox Code Playgroud)
a.foo rescue puts :fail
a.bar rescue puts :fail
a.zim rescue puts :fail
a.dib rescue puts :fail
a.gaz rescue puts :fail
Run Code Online (Sandbox Code Playgroud)
fail
bar
fail
fail
fail
Run Code Online (Sandbox Code Playgroud)
[:foo, :bar, :zim, :dib, :gaz].each { |m| a.send(m) rescue puts :fail }
Run Code Online (Sandbox Code Playgroud)
foo
bar
zim
dib
fail
Run Code Online (Sandbox Code Playgroud)
标有"测试输出"的部分是预期结果.那么为什么我可以简单地访问私有/受保护的方法 …
到目前为止,我在DecisionTree.h文件中的所有内容都是
namespace DecisionTree
{
public static double Entropy(int pos, int neg);
}
Run Code Online (Sandbox Code Playgroud)
而Visual Studio已经突出public并强调了这一点
错误:预期声明.
我错过了什么?
在ruby中,你可以这样做:
class Thing
public
def f1
puts "f1"
end
private
def f2
puts "f2"
end
public
def f3
puts "f3"
end
private
def f4
puts "f4"
end
end
Run Code Online (Sandbox Code Playgroud)
现在f1和f3以及public,f2和f4是私有的.内部发生了什么,允许您调用一个类方法然后更改方法定义?我怎样才能实现相同的功能(表面上是为了创建我自己的java注释)
例如...
class Thing
fun
def f1
puts "hey"
end
notfun
def f2
puts "hey"
end
end
Run Code Online (Sandbox Code Playgroud)
而fun和notfun将改变以下函数定义.
谢谢
最好用一个例子来解释:
file1.rb:
def foo
puts 123
end
Run Code Online (Sandbox Code Playgroud)
file2.rb:
class A
require 'file1'
end
A.new.foo
Run Code Online (Sandbox Code Playgroud)
将给出错误"':私有方法'foo'调用".
我可以通过这样做来解决这个问题,A.new.send("foo")但有没有办法让导入的方法公开?
编辑:澄清一下,我并不困惑包含和要求.此外,我不能使用普通包含的原因(正如许多人正确指出的那样)是这是元编程设置的一部分.我需要允许用户在运行时添加功能; 例如,他可以说"run-this-app --include file1.rb",根据他在file1.rb中编写的代码,应用程序的行为会有所不同.对不起应该解释清楚.
编辑:在阅读了Jorg的回答之后,我意识到我的代码并没有完全符合预期的行为,并且他完美地回答了我的(错误的)问题.我正在尝试做更类似的事情str=(entire file1.rb as string); A.class_exec(str).
请考虑以下代码:
class Base
{
public:
virtual void Foo() {}
};
class Derived : public Base
{
private:
void Foo() {}
};
void func()
{
Base* a = new Derived;
a->Foo(); //fine, calls Derived::Foo()
Derived* b = new Derived;
// b->Foo(); //error
static_cast<Base*>(b)->Foo(); //fine, calls Derived::Foo()
}
Run Code Online (Sandbox Code Playgroud)
关于此事,我听过两种不同的思想流派:
1)保持可访问性与基类相同,因为用户无论如何都可以使用static_cast来获取访问权限.
2)使功能尽可能私密.如果用户需要a-> Foo()而不是b-> Foo(),那么Derived :: Foo应该是私有的.如果需要,它总是可以公开.
是否有理由偏好其中一个?
access-specifier ×10
ruby ×5
c++ ×4
c# ×1
class ×1
code-design ×1
coding-style ×1
pimpl-idiom ×1
public ×1
require ×1
visibility ×1