是否可以创建一个C++头文件(.h)来声明一个类及其公共方法,但是没有定义该类中的私有成员?我发现有几页说你应该在头文件中声明该类及其所有成员,然后在你的cpp文件中单独定义方法.我问,因为我想有在一个Win32 DLL中定义一个类,我希望它是正确的封装:在内部实现这个类的可能会发生变化,包括它的成员,但这些变化不会影响使用该类的代码.
我想如果我有这个,那么它将使编译器无法提前知道我的对象的大小.但是,这应该是罚款,只要编译器是足够聪明的使用构造,只是指针传递给周围的位置在我的对象存储内存,并且从来没有让我跑"的sizeof(MyClass的)".
更新: 感谢所有回答的人!似乎pimpl成语是实现我所谈论的好方法.我要做类似的事情:
我的Win32 DLL文件将有一堆单独的函数,如下所示:
void * __stdcall DogCreate();
int __stdcall DogGetWeight(void * this);
void __stdcall DogSetWeight(void * this, int weight);
Run Code Online (Sandbox Code Playgroud)
这是Microsoft编写DLL文件的典型方式,因此我认为可能有很好的理由.
但是我想利用C++对类的优秀语法,所以我将编写一个包装类来包装所有这些函数.它将有一个成员,这将是"无效*pimpl".这个包装器类将非常简单,我可能只是声明它并在头文件中定义它.但是这个包装类除了让C++代码看起来很漂亮外没有任何其他目的.
railstutorial.org有一个建议让我觉得有点奇怪.
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
end
Run Code Online (Sandbox Code Playgroud)
将include SessionsHelper使得可从方法ApplicationController,是的,但它使他们在任何视图中可用,以及.我知道认证/授权是跨领域的,但这真的是最好的地方吗?
在我看来,这似乎可能过于宽泛.将实现(例如,before_filter有条件地重定向)的代码(如railstutorial.org示例所示)放在一个更常见的包含视图助手的模块中似乎令人惊讶.
在视图中不严格需要的功能是否可以更好地放在ApplicationController或其他地方?
或者我只是在考虑这个问题?
我尝试了解很多次,但我没理解这一点.
封装是一种将类中的字段设为私有并通过公共方法提供对字段的访问的技术.如果某个字段被声明为私有,则该类之外的任何人都无法访问该字段,从而将该字段隐藏在该类中.
我们如何通过setter方法更改字段的值?我们如何防止直接访问字段?封装的真正用途是什么?
正如你可能已经知道,.NET框架的内部保护的访问修饰符工作在一种奇怪的方式:这并不意味着类是保护 和 内部,它说,类保护 或 内部 ; 也就是说,可以从同一程序集中以及从同一层次结构中访问修改后的类或成员.
所以,知道这个:你什么时候使用它?你能给我举个例子吗?.NET基类库中是否有一个很好的,有启发性的用法示例?
我private在C++中尝试访问说明符的有效性.开始:
接口:
// class_A.h
class A
{
public:
void printX();
private:
void actualPrintX();
int x;
};
Run Code Online (Sandbox Code Playgroud)
执行:
// class_A.cpp
void A::printX()
{
actualPrintX();
}
void A::actualPrintX()
{
std::cout << x:
}
Run Code Online (Sandbox Code Playgroud)
我将其构建到静态库(.a/.lib)中.我们现在有一个class_A.h和classA.a(或classA.lib)对.我编辑了class_A.h并从中删除了private:它.
现在在另一个classTester.cpp中:
#include "class_A.h" // the newly edited header
int main()
{
A a;
a.x = 12; // both G++ and VC++ allowed this!
a.printX(); // allowed, as expected
a.actualPrintX(); // allowed by G++, VC++ gave a unresolved linker error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道在篡改了一个库的标题之后所有的赌注都没有了(我的意思是,系统完整性等等)虽然方法很黑,但这真的允许吗?有办法阻止这个吗?或者我在这里做错了什么?
Ecapsulation和信息隐藏之间究竟有什么区别?
我知道将字段设为私有然后制作字段的setter和getter是ecapsulation.However封装意味着这个?
假设我有一个如下所述的课程.
public Class IsThisEncapsulation
{
public int age;
public void setAge(int age)
{
this.age=age;
}
public int getAge()
{
return age;
}
}
Run Code Online (Sandbox Code Playgroud)
现在是IsThisEncapsulation类是Encapsulation的一个例子吗?
现在是否会让上述类私有领域的'年龄'实现信息隐藏?
能否请您给我一些明确的例子,以帮助我清楚地区分这些概念?
如果标题不完全不言自明,这里的代码让我困惑:
public interface IFoo<T>
{
}
public class MyClass : IFoo<MyClass.NestedInMyClass>
{
private class NestedInMyClass
{
}
}
Run Code Online (Sandbox Code Playgroud)
我很惊讶这个编译没有错误.感觉就像我暴露了一种private类型.这不应该是违法的吗?
也许你的回答只是"没有规则反对,所以为什么不行呢?" MyClass.NestedInMyClass即使在"范围"中也许同样令人惊讶.如果我删除了MyClass.资格,它将无法编译.
(如果我改为IFoo<>通用类,它应该成为基类MyClass,这是非法的,因为基类型必须至少与类型本身一样可访问.)
我尝试使用Visual Studio 2010的C#4编译器.
我的特定场景涉及使用私有方法中的正则表达式进行一些文本转换.私有方法调用preg_replace_callback,但似乎回调需要在对象上公开,所以当我不愿意时,我就会突破私有世界并暴露实现细节.
因此,简而言之:我可以使用实例方法作为回调而不会丢失封装吗?
谢谢.
回答什么是你最长的编程假设,结果是不正确的?问题,其中一个错误的假设是:
私有成员变量对实例是私有的,而不是类.
(链接)
我无法理解他正在谈论的内容,任何人都可以用一个例子来解释这是错误/正确的吗?
Meyers在他的书"Effective C++"中提到,在某些情况下,非成员非朋友函数比成员函数更好地封装.
例:
// Web browser allows to clear something
class WebBrowser {
public:
...
void clearCache();
void clearHistory();
void removeCookies();
...
};
Run Code Online (Sandbox Code Playgroud)
许多用户希望一起执行所有这些操作,因此WebBrowser也可能提供一个功能:
class WebBrowser {
public:
...
void clearEverything(); // calls clearCache, clearHistory, removeCookies
...
};
Run Code Online (Sandbox Code Playgroud)
另一种方法是定义非成员非朋友函数.
void clearBrowser(WebBrowser& wb)
{
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
}
Run Code Online (Sandbox Code Playgroud)
非成员函数更好,因为"它不会增加可以访问类的私有部分的函数的数量.",从而导致更好的封装.
喜欢的功能clearBrowser是方便的功能,因为他们不能提供任何功能的WebBrowser一些其他方式的客户端无法获得已.例如,如果clearBrowser不存在,客户可以只打电话clearCache,clearHistory和removeCookies他们自己.
对我而言,便利功能的例子是合理的.但是当非会员版本擅长时,除了便利功能之外还有其他例子吗?
更一般地说,什么时候使用哪些规则?