如何避免代码重复或多次迭代?
考虑下面给出的代码:
struct Person{
enum sex{male,female};
int salary;
};
struct PersonSSN:public Person{
int ssn;
};
我有一个容器,其中仅包含 Person 或 PersonSSN(在编译时已知)按工资值升序排序。我必须编写一个函数 myfunc() 来执行以下操作。
void myfunc(){
if the container contains Person:
print the number of females between two consecutive males.
else if the container contains PersonSSN:
print the number of females between two consecutive males
and
the ssn of the males.
}
对于这个问题我有两种解决方案,但都有一些缺点。
解决方案 1:如果我编写一个用于打印男性之间女性数量的函数和另一个用于打印 ssn 的函数,我必须迭代数据两次,这是昂贵的。
解决方案 2:我可以编写两个从 Myfunc
派生的类,Myfunc
和 MyfuncSSN
,并拥有一个虚函数 process().但是,打印女性数量的代码段必须从
Myfunc
类的 process()
方法复制到 MyfuncSSN
类中。这里不存在代码重用。
什么是更好的解决方案?
Consider the code given below:
struct Person{
enum sex{male,female};
int salary;
};
struct PersonSSN:public Person{
int ssn;
};
I have a container which contains either Person or PersonSSN only, (known at compile time) sorted in the ascending order of salary value. I have to write a function myfunc() which does the following.
void myfunc(){
if the container contains Person:
print the number of females between two consecutive males.
else if the container contains PersonSSN:
print the number of females between two consecutive males
and
the ssn of the males.
}
I have two solutions for this problem but both have some drawbacks.
Solution 1: If I write a function for printing the number of females between males and another function for printing the ssn, I have to iterate through the data twice which is costly.
Solution 2: I can write two classes, Myfunc
, and MyfuncSSN
derived from Myfunc
and have a virtual function process()
. But then the code segment which prints the number females has to be copied from the process()
method of the Myfunc
class into MyfuncSSN
class. Here code re-use is not there.
What is a better solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果你谈论的是编译时的对象识别,那么答案只能是一个——模板。根据您使用的容器类型,它会有所不同,但如果您使用 std::list ,它将
编辑:
如果您想省略双重迭代,我唯一能想到的就是使用signgle模板函数迭代并打印两个连续男性之间的女性数量,调用另一个模板化函数进行 ssn 打印:
这可能适用于这个简单的示例,但我确信对于更复杂的示例 - 假设您想额外打印女性之间的男性数量PersonSSN - 它可能会很短,因为这两个操作(虽然相似)可能无法分成不同类型的功能部分。然后它将需要代码加倍或两次迭代 - 不要认为有办法解决它。
注意:您可能(按照评论中的建议)切换到函数参数中的 const 引用 - 我更习惯使用隐式共享的 qt 容器,因此不需要它。
If you are talking about object recognition at compile time, then the answer can be only one - templates. Depending on which kind of container you use it will vary a bit, but if you use std::list it would be
EDIT:
if you want to ommit double iteration the only thing i can imagine to do would be to use signgle template function for iterating and printing the number of females between two consecutive males calling another templated function for ssn printing:
This might work for this simple example, but i am sure that for more complicated examples - say you want to print addionally number of males between females for PersonSSN - it might come short, as those two operations (while similar) might turn out to be impossible to separate into part with functionality for different types. Then it will need code doubling or double iteration - don't think there is way around it.
Note: you might (as suggested in comments) switch to const-references in function-args - i am more used to qt-containers which use implicite sharing and therefore dont need it.
这个例子在很多不同的层面上都是错误的:)
理想情况下,“Person”将是一个类; “name”、“sex”和“SSN”都将是基类的成员,“process()”将是 method() 或 virtual method()。
问:是否有可能将 Person 和 PersonSSN 更改为类,并将“process()”作为方法?
问:您的程序如何“知道”它是否有“Person”记录或“PersonSSN”记录?您可以将其作为“process()”函数的参数吗?
附录 9.16.2011:价值
百万美元的问题是“您的代码如何区分“Person”和“PersonSSN”?”
如果您使用类,则可以使用“typeof”(不令人满意),或者您可以将特定于类的行为与类方法联系起来(首选,以及“模板”建议中建议的内容)。
您还需要至少三个不同的类:“Person”类(看起来和行为都像人)、“PersonSSN”类(具有额外的数据和可能的额外行为)...以及“ueber-class”知道如何计算人和 PersonSSN。
所以,是的,我建议应该有一些类HAS,或者使用“Persons”和“PersonSSNs”。
是的,您可以将代码分解为一个类使用“Process-count-consecutive”,另一个类调用父类“Process-count-consecutive”,并添加一个新的“print ssn”。
This example is so wrong on so many different levels :)
Ideally, "Person" would be a class; "name", "sex" and "SSN" would all be members of the base class, and "process()" would be either a method() or a virtual method().
Q: Is there any chance of changing Person and PersonSSN into classes, and making "process()" a method?
Q: How does your program "know" whether it's got a "Person" record, or a "PersonSSN" record? Can you make this a parameter into your "process()" function?
ADDENDUM 9.16.2011:
The million$ question is "How can your code distinguish between a 'Person' and a 'PersonSSN'?"
If you use a class, you can use "typeof" (unsatisfactory), or you can tie the class-specific behavor to a class method (preferred, and what was suggested with the "template" suggestion).
You also need at least THREE different classes: the "Person" class (which looks and behaves like a person), a "PersonSSN" class (which has the extra data and possibly extra behavior) ... and an "ueber-class" that knows how to COUNT Persons and PersonSSN's.
So yes, I'm suggesting there should be some class that HAS, or that USES "Persons" and "PersonSSNs".
And yes, you can factor your code that one class uses "Process-count-consecutive", and another calls the parent "Process-count-consecutive", and adds a new "print ssn".