小编sho*_*tsy的帖子

如何为二进制兼容的可扩展性设计C++ API

我正在为C++库设计一个API,它将分发在一个dll/shared对象中.该库包含具有虚函数的多态类.我担心如果我在DLL API上公开这些虚函数,我就不会使用更多虚函数扩展相同的类,而不会破坏与为以前版本的库构建的应用程序的二进制兼容性.

一种选择是使用PImpl习惯用法来隐藏所有具有虚函数的类,但这似乎也有它的局限性:这样,应用程序就失去了对类的子类进行子类化并覆盖虚方法的可能性.

您将如何设计一个可以在应用程序中进行子类化的API类,而不会失去在新版本的dll中使用(非抽象)虚拟方法扩展API同时保持向后二进制兼容的可能性?

更新:库的目标平台是windows/msvc和linux/gcc.

c++ virtual binary-compatibility

33
推荐指数
2
解决办法
2万
查看次数

将自定义类型转换注入.NET库类

我想通过C#中的Convert.ChangeType实现两个库类之间的转换.我可以改变这两种类型.例如,在Guid和byte []之间进行转换.

Guid g = new Guid();
object o1 = g;
byte[] b = (byte[]) Convert.ChangeType(o1, typeof(byte[])); // throws exception
Run Code Online (Sandbox Code Playgroud)

我知道Guid提供了一个ToByteArray()方法,但我希望在Guid转换为byte []时调用它.这背后的原因是转换也发生在我无法修改的库代码(AseDataAdapter)中.那么是否可以在两种类型之间定义转换规则而无需修改两个类中任何一个的源代码?

我正在尝试使用TypeConverter,但似乎也没有工作:

Guid g = new Guid();
TypeConverter tc = TypeDescriptor.GetConverter(typeof(Guid));
byte[] b2 = (byte[])tc.ConvertTo(g, typeof(byte[])); // throws exception
Run Code Online (Sandbox Code Playgroud)

变量tc设置为System.ComponentModel.GuidConverter,它不支持转换为byte [].我可以为同一个班级安排两个TypeConverters吗?即使我可以,我不需要在类的源代码前添加属性来分配TypeConverter吗?

谢谢

.net c# guid

22
推荐指数
1
解决办法
5874
查看次数

List <T> .AddRange实现次优

分析我的C#应用​​程序表明花费了大量时间List<T>.AddRange.使用Reflector查看此方法中的代码表明它调用的List<T>.InsertRange是这样实现的:

public void InsertRange(int index, IEnumerable<T> collection)
{
    if (collection == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
    }
    if (index > this._size)
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
    }
    ICollection<T> is2 = collection as ICollection<T>;
    if (is2 != null)
    {
        int count = is2.Count;
        if (count > 0)
        {
            this.EnsureCapacity(this._size + count);
            if (index < this._size)
            {
                Array.Copy(this._items, index, this._items, index + count, this._size - index);
            }
            if (this == is2)
            {
                Array.Copy(this._items, 0, this._items, index, index);
                Array.Copy(this._items, (int) (index + count), …
Run Code Online (Sandbox Code Playgroud)

.net c# performance list addrange

20
推荐指数
1
解决办法
9242
查看次数

在哪些情况下IEnumerable <T> .Count优化?

使用反射器我注意到该System.Linq.Enumerable.Count方法有一个条件来优化它,因为IEnumerable<T>传递实际上是一个ICollection<T>.如果转换成功,则Count方法不需要迭代每个元素,但可以调用ICollection的Count方法.

基于此,我开始认为IEnumerable<T>可以像集合的只读视图一样使用,而不会出现我最初基于API的性能损失.IEnumerable<T>

我感兴趣的是,CountIEnumerable<T>a是一个Select语句的结果时,仍然保持优化ICollection,但是基于反映的代码,这种情况没有被优化,并且需要遍历所有元素.

你从反射器得出相同的结论吗?缺少这种优化背后的原因是什么?我似乎在这个常见的操作中浪费了很多时间.即使可以在不这样做的情况下确定Count ,规范是否要求评估每个元素?

c# optimization ienumerable count

14
推荐指数
1
解决办法
1561
查看次数

如何打印StackOverflowException的堆栈跟踪

我正在开发一个发生StackOverflowException的.Net 2.0应用程序.有没有办法在应用程序中止之前/期间打印/记录堆栈跟踪?这是一个长期运行的服务器端进程,很难在调试器下执行.我知道无法捕获StackOverflowException.

.net stack-overflow stack-trace

9
推荐指数
1
解决办法
5625
查看次数

编译器绕互斥边界重新排序?

假设我有自己的非内联函数LockMutex和UnlockMutex,它们正在使用一些适当的互斥体 - 例如boost - inside.对于LockMutex和UnlockMutex的调用,编译器如何知道不重新排序其他操作?它不可能知道如何在其他编译单元中实现这些功能.

void SomeClass::store(int i)
{
  LockMutex(_m);
  _field = i;  // could the compiler move this around?
  UnlockMutex(_m);
}
Run Code Online (Sandbox Code Playgroud)

ps:应该使用类的实例来保存锁以保证解锁.我把它留下来简化示例.

c++ compiler-optimization memory-barriers

7
推荐指数
1
解决办法
1533
查看次数

没有绑定检查的C#byte []比较

我正在寻找性能有效的方法来比较两个字节[]的相等性.大小超过1 MB,因此应尽量减少每个数组元素的开销.

我的目标是通过避免两个数组的重复绑定检查来击败每个项目的速度SequenceEqual手动编码的for循环.以同样的方式导致快速,会导致什么?Array.Copymemcpymemcmp

c# arrays comparison performance byte

6
推荐指数
2
解决办法
2701
查看次数

高效传递std :: vector

当C++函数接受一个std::vector参数时,通常的模式是通过const引用传递它,例如:

int sum2(const std::vector<int> &v)
{
   int s = 0;
   for(size_t i = 0; i < v.size(); i++) s += fn(v[i]);
   return s;
}
Run Code Online (Sandbox Code Playgroud)

我相信,在双解除引用此代码结果时的矢量元素被访问,这是因为CPU应该首先解除引用v读取指针的第一个元素,该指针需要再次解除引用读取第一元件.我希望在堆栈上传递矢量对象的浅表副本会更有效.这样的浅拷贝将封装指向第一个元素的指针和大小,指针引用与原始向量相同的存储区域.

int sum2(vector_ref<int> v)
{
   int s = 0;
   for(size_t i = 0; i < v.size(); i++) s += fn(v[i]);
   return s;
}
Run Code Online (Sandbox Code Playgroud)

类似的性能,但通过传递随机访问迭代器对可以实现更少的便利性.我的问题是:这个想法有什么缺陷?我希望聪明的人能够接受支付矢量参考的性能成本或处理迭代器的不便之处.

编辑:根据下面的编辑,如果我只是将建议的vector_ref类重命名为切片范围,请考虑这种情况.目的是使用具有更自然语法的随机访问迭代器对.

c++ arguments stl vector

5
推荐指数
2
解决办法
2万
查看次数

避免切片异常类型(C++)

我正在为我的库设计一个C++的异常层次结构."层次结构"是从std :: runtime_error派生的4个类.我想避免异常类的切片问题,因此使复制构造函数受到保护.但显然gcc需要在抛出它们的实例时调用复制构造函数,因此抱怨受保护的复制构造函数.Visual C++ 8.0编译相同的代码.是否有任何可移植的方法来解决异常类的切片问题?标准是否说明实现是否可以/应该要求抛出要抛出的类的复制构造函数?

c++ gcc exception derived object-slicing

5
推荐指数
3
解决办法
2135
查看次数

如何监视.Net服务器应用程序是否存在致命异常?

我正在开发一个.Net服务器应用程序,它应该不断运行.我希望每次服务器进程因任何原因终止时都会发送通知电子邮件.理想情况下,如果异常导致终止,则电子邮件应包含异常消息和堆栈跟踪.我知道某些例外是无法捕获的,例如StackOverflowException.那么如何记录/发送StackOverflowException服务器进程中发生的通知?

我正在考虑创建第二个进程来监视服务器进程.但是,如何获得异常的详细信息呢?

.net stack-overflow email

5
推荐指数
1
解决办法
491
查看次数

C++标准在哪里定义float类型的值范围?

据我所知,浮点值的形式为n*2 ^ e,其中

  • 浮点范围为n = - (2 ^ 23-1) - (2 ^ 23-1),e = -126 - 127,
  • 双范围是n = - (2 ^ 52-1) - (2 ^ 52-1),并且e = -1022-1023

我正在查看C++标准,但未能找到标准指定的位置,或者要求float,double和long double类型与其他(IEEE)标准中定义的范围相关联.我在3.9.1.8中找到的唯一相关内容是:

有三种浮点类型:float,double和long double.double类型提供至少与float一样多的精度,long double类型提供至少与double一样多的精度.float类型的值集是double类型的值集的子集; double类型的值集是long double类型的值集的子集.浮点类型的值表示是实现定义的.

并没有提到该类型提供的最小范围.

标准在何处/如何指定浮点类型的(最小?)值范围?或者编译器可以自由选择任何值范围并且仍然符合标准吗?

c++ floating-point double standards range

2
推荐指数
1
解决办法
3682
查看次数