- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在创建一个 C++ 类,它包装一个浮点二维数组并提供一些额外的功能。我想将数组的形状作为参数传递给构造函数,请参见下面的代码(类 Block 部分)。以注释“//here”结尾的行会在编译期间导致错误,因为 _nx 和 _ny 在那时是未知的。围绕这个有两种解决方案(我认为):一种是使用指针(参见下面代码中的解决方案 1)并动态分配数组;另一个是使用模板(参见下面代码中的解决方案 2),但我有几个不使用它们的原因:
另外,我不想使用STL vector,因为创建后数组大小是固定的;我也在做数值计算,所以“原始”数组更适合我。
我在 SO 中搜索过,有五六个问题问类似的问题,但没有结论哪个更好,而且它们都不是从数字的角度来看的,所以 vector 或 new/detele 对他们来说是很好的答案- 但不适合我。我发布这个问题的另一个原因是我想知道我在使用 C++ 功能时是否过于严格。由于我将广泛使用 C++,因此了解 C++ 的局限性并停止询问/搜索不存在的某些功能非常重要。
#include <iostream>
#include <memory>
using namespace std;
class Block
{
public:
Block(int nx, int ny):_nx(nx),_ny(ny){}
void Report(void)
{
cout << "Block With Size ["<<_nx<<","<<_ny<<"]\n";
}
private:
const int _nx, _ny;
double _data[_nx][_ny]; // here
};
/// Solution 1, using auto_ptr
class BlockAuto
{
public:
BlockAuto(int nx, int ny):_nx(nx),_ny(ny),_data(new double[_nx*_ny]){}
void Report(void)
{
cout << "BlockAuto With Size ["<<_nx<<","<<_ny<<"]\n";
}
private:
const int _nx;
const int _ny;
const auto_ptr<double> _data;
};
/// Solution 2, using template
template<unsigned int nx, unsigned int ny>
class BlockTpl
{
public:
BlockTpl():_nx(nx),_ny(ny){}
void Report(void)
{
cout << "BlockTpl With Size ["<<_nx<<","<<_ny<<"]\n";
}
private:
const int _nx;
const int _ny;
double _data[nx][ny]; // uncomfortable here, can't use _nx, _ny
};
int main(int argc, const char *argv[])
{
Block b(3,3);
b.Report();
BlockAuto ba(3,3);
ba.Report();
BlockTpl<3,4> bt;
bt.Report();
return 0;
}
最佳答案
只需使用一个std::vector
。一周前我遇到了同样的决策问题并问过here .
如果您使用 reserve()
,它不会使您的 vector
多次重新分配自身(如果有的话),那么 vectors
不会将影响您的项目的性能。换句话说,vector
不太可能成为您的瓶颈。
请注意,在 C++
中,vectors
被广泛使用,因此在 release 模式
中,优化他们真的很有效率。
或者等待std::dynarray
待介绍! (不幸的是,不是在 C++14
中,而是在 array TS
或 C++17
中)。 Source , 归功于 manlio。
永远不要忘记:过早的优化是万恶之源。 - Knuth。
不相信我?你不应该!亲自试验并找出答案!
这是我的实验,当我遇到与您完全相同的问题时,我可以说服自己。
实验代码:
#include <iostream>
#include <vector>
#include <ctime>
#include <ratio>
#include <chrono>
using namespace std;
int main() {
const int N = 100000;
cout << "Creating, filling and accessing an array of " << N << " elements.\n";
using namespace std::chrono;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
int array[N];
for(int i = 0; i < N; ++i)
array[i] = i;
for(int i = 0; i < N; ++i)
array[i] += 5;
high_resolution_clock::time_point t2 = high_resolution_clock::now();
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
std::cout << "It took me " << time_span.count() << " seconds.";
std::cout << std::endl;
cout << "Creating, filling and accessing an vector of " << N << " elements.\n";
t1 = high_resolution_clock::now();
vector<int> v;
v.reserve(N);
for(int i = 0; i < N; ++i)
v.emplace_back(i);
for(int i = 0; i < N; ++i)
v[i] += 5;
t2 = high_resolution_clock::now();
time_span = duration_cast<duration<double>>(t2 - t1);
std::cout << "It took me " << time_span.count() << " seconds.";
std::cout << std::endl;
return 0;
}
结果(注意 -o2
编译器标志):
samaras@samaras-A15:~$ g++ -std=gnu++0x -o2 px.cpp
samaras@samaras-A15:~$ ./a.out
Creating, filling and accessing an array of 100000 elements.
It took me 0.002978 seconds.
Creating, filling and accessing an vector of 100000 elements.
It took me 0.002264 seconds.
所以,只是一个std::vector
。 :) 我很确定您知道如何为此更改代码,您不需要我告诉您(是这样,当然让我知道 :))。
您可以尝试其他时间方法,在我的 pseudo-site 中找到.
关于c++ - 数组大小作为构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23703837/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!