我对C++类结构感到困惑.
我有一个名为FxMathFunctions.h的.h和一个名为FxMathFunctions.cpp的.cpp
.h开头像:
class FxMathFunctions
{
public:
FxMathFunctions();
~FxMathFunctions();
Run Code Online (Sandbox Code Playgroud)
并在.cpp
我有:
#include "FxBasicTypes.h"
#include "FxMathFunctions.h"
FxMathFunctions::FxMathFunctions() {}
FxMathFunctions::~FxMathFunctions() {}
Run Code Online (Sandbox Code Playgroud)
我收到的错误如下:
error: new types may not be defined in a return type
error: return type specification for constructor invalid
Run Code Online (Sandbox Code Playgroud)
这必须与某个地方的定义有关,但我不知道这可能发生在哪里.
我有一个界面 - 这是一个很好的人为的版本作为一个例子:
public interface Particle {
enum Charge {
POSITIVE, NEGATIVE
}
Charge getCharge();
double getMass();
etc...
}
Run Code Online (Sandbox Code Playgroud)
如果我将Charge枚举定义为静态,那么这种实现方式有什么不同- 即这有什么影响:
public interface Particle {
static enum Charge {
POSITIVE, NEGATIVE
}
Charge getCharge();
double getMass();
etc...
}
Run Code Online (Sandbox Code Playgroud) 处理一个小的Ruby脚本,该脚本可以访问Web并抓取各种服务.我有一个包含几个类的模块:
module Crawler
class Runner
class Options
class Engine
end
Run Code Online (Sandbox Code Playgroud)
我想在所有这些类中共享一个记录器.通常我只是将它放在模块中的常量中并像这样引用它:
Crawler::LOGGER.info("Hello, world")
Run Code Online (Sandbox Code Playgroud)
问题是,在我知道输出的位置之前,我无法创建我的记录器实例.您可以通过命令行启动爬网程序,此时您可以告诉它您要在开发中运行(日志输出转到STDOUT)或生产(日志输出转到文件,crawler.log):
crawler --environment=production
Run Code Online (Sandbox Code Playgroud)
我有一个类Options解析通过命令行传入的选项.只有在那时我才知道如何使用正确的输出位置实例化记录器.
所以,我的问题是:我如何/在哪里放置我的记录器对象,以便我的所有类都可以访问它?
我可以将我的记录器实例传递给new()我创建的每个类实例的每个调用,但我知道必须有一个更好的Rubyish方法来实现它.我正在想象与模块共享的一些奇怪的类变量class << self或其他魔法.:)
更多细节:Runner通过将命令行选项传递给Options类来启动所有内容,并获取具有几个实例变量的对象:
module Crawler
class Runner
def initialize(argv)
@options = Options.new(argv)
# feels like logger initialization should go here
# @options.log_output => STDOUT or string (log file name)
# @options.log_level => Logger::DEBUG or Logger::INFO
@engine = Engine.new()
end
def run
@engine.go
end
end
end
runner = Runner.new(ARGV)
runner.run
Run Code Online (Sandbox Code Playgroud)
我需要代码Engine …
让我们考虑python(3.x)脚本:
main.py:
from test.team import team
from test.user import user
if __name__ == '__main__':
u = user()
t = team()
u.setTeam(t)
t.setLeader(u)
Run Code Online (Sandbox Code Playgroud)
测试/ user.py:
from test.team import team
class user:
def setTeam(self, t):
if issubclass(t, team.__class__):
self.team = t
Run Code Online (Sandbox Code Playgroud)
测试/ team.py:
from test.user import user
class team:
def setLeader(self, u):
if issubclass(u, user.__class__):
self.leader = u
Run Code Online (Sandbox Code Playgroud)
现在,当然,我已经获得了循环导入和出色的ImportError.
所以,不是pythonista,我有三个问题.首先:
一世.我怎么能让这个东西工作?
并且,知道某人将不可避免地说"循环导入总是表明设计问题",第二个问题来自:
II.为什么这个设计不好?
最后,第三个:
III.什么是更好的选择?
确切地说,上面的类型检查只是一个例子,还有一个基于类的索引层,它允许ie.发现所有用户都是一个团队的成员(用户类有许多子类,因此索引加倍,对于一般用户和每个特定子类)或所有团队都将用户作为成员
编辑:
我希望更详细的例子能够澄清我试图实现的目标.为了可读性省略了文件(但是有一个300kb的源文件让我感到害怕,所以请假设每个类都在不同的文件中)
# ENTITY
class Entity:
_id = None
_defs = {}
_data = None
def …Run Code Online (Sandbox Code Playgroud) 在C#泛型之前,每个人都会通过创建实现IEnumerable的集合库来为其业务对象编写集合
IE:
public class CollectionBase : IEnumerable
Run Code Online (Sandbox Code Playgroud)
然后从中派生出他们的Business Object集合.
public class BusinessObjectCollection : CollectionBase
Run Code Online (Sandbox Code Playgroud)
现在使用通用列表类,是否有人只使用它?我发现我使用了两种技术的妥协:
public class BusinessObjectCollection : List<BusinessObject>
Run Code Online (Sandbox Code Playgroud)
我这样做是因为我喜欢强类型名称而不是仅仅传递列表.
你的方法是什么?
如果要将某个常量值与类关联,可以使用以下两种方法来实现相同的目标:
class Foo
{
public:
static const size_t Life = 42;
};
class Bar
{
public:
enum {Life = 42};
};
Run Code Online (Sandbox Code Playgroud)
在语法和语义上,从客户的角度来看,它们似乎是相同的:
size_t fooLife = Foo::Life;
size_t barLife = Bar::Life;
Run Code Online (Sandbox Code Playgroud)
除了纯粹的风格之外,还有什么理由可以解释为什么一个人比另一个人更可取?
我想要一个实现固定大小循环缓冲区的简单类.它应该是高效的,容易在眼睛上,一般打字.
编辑:目前它不需要具备MT功能.我总是可以在以后添加一个锁,在任何情况下它都不会是高并发性的.
方法应该是:.Add和我猜.List,我检索所有条目.第二个想法,我认为应该通过索引器完成检索.在任何时候,我都希望能够通过索引检索缓冲区中的任何元素.但请记住,从一个时刻到下一个Element [n]可能会有所不同,因为循环缓冲区填满并翻转.
这不是一个堆栈,它是一个循环缓冲区.关于"溢出":我希望内部会有一个包含项目的数组,随着时间的推移,缓冲区的头部和尾部将围绕该固定数组旋转.但这应该是用户不可见的.应该没有外部可检测的"溢出"事件或行为.
这不是学校作业 - 它通常用于MRU缓存或固定大小的事务或事件日志.
我看了道格拉斯克罗克福德关于Javascript好的部分的演讲,我的眼睛被打开了.有一次,他说,"Javascript是唯一一种优秀的程序员相信他们可以有效地使用它而不需要学习它的语言." 然后我意识到,我就是那个人.
在那次演讲中,他做了一些声明,对我而言,非常令人惊讶和富有洞察力.例如,JavaScript是地球上最重要的编程语言.或者它是这个星球上最流行的语言.并且,它以许多严肃的方式被打破.
对我来说,他最令人惊讶的声明是"新危险".他不再使用它了.他也this没用.
他为Javascript中的构造函数提供了一个有趣的模式,一个允许私有和公共成员变量的模式,并且既不依赖new也不依赖this.它看起来像这样:
// neo-classical constructor
var container = function(initialParam) {
var instance = {}; // empty object
// private members
var privateField_Value = 0;
var privateField_Name = "default";
var privateMethod_M1 = function (a,b,c) {
// arbitrary
};
// initialParam is optional
if (typeof initialParam !== "undefined") {
privateField_Name= initialParam;
}
// public members
instance.publicMethod = function(a, b, c) {
// because of closures,
// can call private methods …Run Code Online (Sandbox Code Playgroud) 如果我创建一个MyClass类并且它有一些私有成员说MyOtherClass,那么将MyOtherClass作为指针是否更好?将它作为存储在内存中的指针而不是指针也意味着什么?创建类时是否会创建对象?
我注意到QT中的示例通常在类成员时将类成员声明为指针.
问候
标记
有一段时间我一直在设计我的类接口是最小的,更喜欢命名空间包装的非成员函数而不是成员函数.基本上遵循Scott Meyer在非成员函数如何改进封装的文章中的建议.
我在一些小规模的项目中一直在这方面做得很好,但我想知道它在更大规模上的运作情况.是否有任何大型的,备受推崇的开源C++项目,我可以看看,也许参考这个建议被强烈遵循的地方?
更新:感谢所有的意见,但我并不是真的对意见感兴趣,而是在大规模的实践中找出它的效果.尼克的答案在这方面最接近,但我希望能够看到代码.任何形式的实践经验的详细描述(积极,消极,实际考虑等)也是可以接受的.
class-design ×10
c++ ×4
c# ×2
java ×2
.net ×1
collections ×1
compilation ×1
constructor ×1
dependencies ×1
enums ×1
generics ×1
javascript ×1
logging ×1
member ×1
memory ×1
oop ×1
pointers ×1
python ×1
ruby ×1