我知道+ =运算符会将一个方法添加到由Delegate基础对象维护的调用列表中
using System;
class Program
{
delegate void MyDelegate(int n);
void Foo(int n)
{
Console.WriteLine("n = {0}", n)
}
static void Main(string[] args)
{
MyDelegate d = new MyDelegate(Foo);
d += Foo; // add Foo again
d.Invoke(3); // Foo is invoked twice as Foo appears two times in invocation list
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我查看MSDN Delegate时,MulticastDelegate我找不到+ =运算符的任何定义.它是如何起作用的?自动生成编译魔术?
以下是从MSDN,try-catch(C#参考)中获取的示例
catch (ArgumentException e) if (e.ParamName == "…")
{
}
Run Code Online (Sandbox Code Playgroud)
他们也说
使用catch参数是筛选要处理的异常的一种方法.您还可以使用谓词表达式来进一步检查异常以决定是否处理它.如果谓词表达式返回false,则继续搜索处理程序.
捕获和重新抛出(如下所述)优先使用异常过滤器,因为过滤器会使堆栈不受损害.如果稍后的处理程序转储堆栈,您可以看到异常最初来自的位置,而不仅仅是它重新抛出的最后位置.异常过滤器表达式的常见用法是记录.您可以创建一个始终返回false的谓词函数,该函数也会输出到日志,您可以记录异常,而无需处理它们并重新抛出.
我的代码:
static bool LogFunction(System.Exception ex)
{
System.Console.WriteLine("Writing to logfile: {0}", ex.Message);
return false;
}
static void Main(string[] args)
{
try
{
throw new System.ArgumentException("The exception message...");
}
catch(System.Exception ex) if (LogFunction(ex))
{
System.Console.WriteLine("This will not be executed, ever!");
}
catch(System.ArgumentException ex)
{
// ....
}
}
Run Code Online (Sandbox Code Playgroud)
现在,编译器不会编译它(csc.exe),给出以下错误消息:
error CS1003: Syntax error, 'when' expected
Run Code Online (Sandbox Code Playgroud)
编辑:编译器引发该行的错误
error CS1003: Syntax error, 'when' expected
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
谢谢.
编辑:我向MSDN提交了反馈,指出了文档中的错误.
问题:隐式bool转换是否总是回退到尝试隐式转换为void*?(如果存在类型的转换函数).如果是这样,为什么?
考虑以下简短程序:
#include <iostream>
class Foo{
public:
operator void*() const
{
std::cout << "operator void*() const" << std::endl;
return 0;
}
};
int main()
{
Foo f;
if(f)
std::cout << "True" << std::endl;
else
std::cout << "False" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该程序的输出是:
operator void*() const
False
Run Code Online (Sandbox Code Playgroud)
意思是,void*被称为转换函数.如果我们explicit在转换函数前面标记限定符,则隐式转换void*将失败.
编辑:
似乎很多答案是"空指针可以转换为false".我理解这一点,我的问题是关于"如果我不能直接调用operator bool()那么我将尝试转换为任何指针".
假设我使用MinGW 64(g ++编译器)创建并编译了一个简单的程序.在我的计算机上运行该程序,并在Process Explorer中查找程序正在使用的DLL文件,我发现(在许多其他程序中):
libgcc_s_seh-1.dll
libstdc++6.dll
libwinpthread-1.dll
Run Code Online (Sandbox Code Playgroud)
这些是我的MinGW安装文件夹中唯一的.使用的其余DLL文件位于C:\Windows.
问题1:
MinGW DLL文件是MinGW C++运行时库(可以这么说)吗?它们的用途与msvcrXXX.dll(XXX = Microsoft运行时库的版本)相同.
问题2:
如果我想在没有安装MinGW的其他计算机上运行该应用程序,是否足以包含上面列出的那些DLL文件(即将它们放在与我的可执行文件相同的文件夹中)以使其在另一台计算机上运行(我们假设其他计算机也是64位Windows机器).如果是,这是否意味着我们基本上将MinGW C++运行时与我们的可执行文件一起发布.如果不是,为什么?
我对Python很新,但在C++方面有点经验,这就是为什么下面的代码示例让我感到困惑的原因.
def foo():
y = x
print y
x = 5
foo()
Run Code Online (Sandbox Code Playgroud)
运行此代码将打印值5.如何在foo()中知道变量x的值?上面的代码不会在C++中运行,如果我们这样做了会:
#include <iostream>
int x = 5;
void foo()
{
std::cout << "x = " << x << std::endl;
}
int main()
{
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因为这里x是全局范围中的变量,它在foo()之前被声明(和定义).它是否在Python中工作,因为x被添加到全局符号表中?
谢谢你的帮助!
我是否可以总是在下面的代码中以eximlified方式替换InputIterators的指针?
int a[] = {5, 6, 7, 8, 9, 10};
std::list<int> l(a, a + 4); // 5, 6, 7, 8
Run Code Online (Sandbox Code Playgroud)
列表的构造函数声明是(省略分配器部分)
list (InputIterator first, InputIterator last);
Run Code Online (Sandbox Code Playgroud)
但是从C++引用来看,似乎任何支持诸如++(增量)和*(解引用)等动作的东西都可以用作InputIterators?
谢谢.
(在使用g ++编译器的Win32API上下文中询问此问题).我很难理解为什么以下代码行不起作用
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
Run Code Online (Sandbox Code Playgroud)
wndclass是WNDCLASSEX结构的一个实例,Windows API明确指出其成员hbrBackground的类型是HBRUSH.此外,HBRUSH只是HANDLE的typedef,而HANDLE又是void*的typedef.因此,HBRUSH应为void*类型.现在,GetStockObject函数的返回类型是HGDIOBJ,它也被命名为HANDLE,因此是void*.
Windows数据类型 http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
GetStockObject http://msdn.microsoft.com/en-us/library/dd144925(v=vs.85).aspx
WNDCLASSEX http://msdn.microsoft.com/en-us/library/windows/desktop/ms633577(v=vs.85).aspx
为什么编译时会出现以下错误:
invalid conversion from 'HGDIOBJ {aka void*}' to 'HBRUSH' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)
如果我从GetStockObject显式地转换返回的值,它可以工作
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
Run Code Online (Sandbox Code Playgroud)
感谢您的任何帮助.
以下内容来自 libcurl 主页:
从同一服务器传输多个文件时,curl 和 libcurl 对持久连接具有出色的支持。Curl 将尝试重用同一命令行/配置文件中指定的所有 URL 的连接,并且 libcurl 将重用使用同一 libcurl 句柄进行的所有传输的连接。
可以肯定的是,如果我创建一个 CURL 句柄 (curl_easy_init()) 并设置它的标头,发出 HTTP 请求,然后更改标头并发出另一个请求,libcurl 仍将尝试使用持久连接,即使标头具有改变了?
libcurl 主页还说
如果您使用 easy 接口,并且调用curl_easy_cleanup,则 libcurl 持有的所有可能打开的连接都将被关闭并被遗忘。
因此,只要我不调用curl_easy_cleanup,即使请求是使用不同的标头发出的,CURL 也会尝试重新使用相同的连接?
谢谢。
在C#中,我们定义一个属性如下:
// m_age is a private int in the class Employee
public int Age
{
get {return m_age;}
set {m_age = value;}
}
Run Code Online (Sandbox Code Playgroud)
现在,当我这样做
static void Main()
{
Employee e = new Employee(age: 28); // Create new Employee
System.Console.WriteLine("Age: {0}", e.Age); // Prints 28
// Now increase age by 1
++e.Age;
System.Console.WriteLine("Age: {0}", e.Age); // Prints 29
}
Run Code Online (Sandbox Code Playgroud)
为什么呢
++e.Age;
Run Code Online (Sandbox Code Playgroud)
工作?我做了一些搜索并找到了属性 - 按价值或参考?
这篇文章有一个答案:
从技术上讲,它总是靠价值,但你必须了解传递的是什么.因为它是一个引用类型,所以你传回一个引用(但是按值).
希望有道理.您总是按值传递结果,但如果类型是引用,则您将按值传递引用,这意味着您可以更改对象,但不能更改它引用的对象.
(我对值类型和引用类型有很好的理解,因此我的困惑).
现在,如果确实如此
e.Age
Run Code Online (Sandbox Code Playgroud)
返回m_age 的副本(int是值类型),我们不会将增量++应用于副本吗?
或者......以下是真的吗?
++e.Age;
Run Code Online (Sandbox Code Playgroud)
完全相同/被翻译成
e.Age = e.Age …Run Code Online (Sandbox Code Playgroud) 我刚看到一些我不太了解的东西.我认为这static_cast<TYPE>(variable)相当于(或更好/更安全)TYPE(variable).但是,以下代码不起作用
HMENU hMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();
// File
AppendMenu(hSubMenu, MF_STRING, WndClass_main::ID_FILE_EXIT, "&Quit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, static_cast<intptr_t>(hSubMenu), "&File");
Run Code Online (Sandbox Code Playgroud)
我的编译器说它无法转换HMENU为intptr_t.我有一个64位系统顺便说一句,这与间铸造interfers void*和int?但是,根据我的理解,类型intptr_t(在cstdint中定义)保证足够大void*.
有趣的是,以下(注意不同的演员)有效:
HMENU hMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();
// File
AppendMenu(hSubMenu, MF_STRING, WndClass_main::ID_FILE_EXIT, "&Quit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (intptr_t)(hSubMenu), "&File");
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我有一个关于使用libcurl(C++)执行并行HTTP请求的安全性的问题.在阅读这个问题时,请记住我对HTTP请求的了解有限.
基本上,假设我有两个(或更多)线程,每个线程每秒发出一次HTTP请求.(所有请求都是在同一台服务器上).我的程序(或其他什么?)如何跟踪HTTP响应属于哪个步骤?我的意思是,我可以确定如果请求A是从线程1发送的,并且同时从线程2请求B,并且同时恢复响应,则正确的响应(响应A)将转到线程1并且响应B到线程2?
请原谅我对这件事的无知.
谢谢.
我对调用 C++ 函数时函数参数的计算顺序感到困惑。我可能解释错了,所以请解释是否是这种情况。
例如,Charles Petzold 的传奇著作“Programming Windows”包含如下代码:
// hdc = handle to device context
// x, y = coordinates of where to output text
char szBuffer[64];
TextOut(hdc, x, y, szBuffer, snprintf(szBuffer, 64, "My text goes here"));
Run Code Online (Sandbox Code Playgroud)
现在,最后一个参数是
snprintf(szBuffer, 64, "My text goes here")
Run Code Online (Sandbox Code Playgroud)
它返回写入 char[] szBuffer 的字符数。它还将文本“My text go here”写入 char[] szBuffer。第四个参数是 szBuffer,它包含要写入的文本。但是,我们可以看到 szBuffer 填充在第五个参数中,告诉我们不知何故是表达式
// argument 5
snprintf(szBuffer, 64, "My text goes here")
Run Code Online (Sandbox Code Playgroud)
之前评估过
// argument 4
szBuffer
Run Code Online (Sandbox Code Playgroud)
好的。总是这样吗?评估总是从右到左进行?查看默认调用约定__cdecl:
__cdecl 调用约定的主要特点是:
参数从右向左传递,并放置在堆栈中。
堆栈清理由调用者执行。
函数名称通过在其前面加上下划线字符 '_' 来修饰。
(来源: …
我目前正在阅读Troelsen的书籍C#和.NET 4.5框架.书中有一节他有一个覆盖的例子
public virtual int GetHashCode(); // Defined in System.Object
Run Code Online (Sandbox Code Playgroud)
他说(以下引用来自Troelsen的书):
鉴于String类已经具有使用String的字符数据来计算哈希值的实体哈希码算法,如果您可以在类上识别对于所有实例应该是唯一的一段字段数据(例如社会安全号码,只需在该字段数据上调用GetHashCode().
基本上他说的是某个类有一个成员(自动只读属性)
public string SSN {get; }
Run Code Online (Sandbox Code Playgroud)
并且该类的每个实例都将具有唯一的字符串值.现在,在假设该
// s1 and s2 are strings
s1.GetHashCode() != s2.GetHashCode(); // Assumption: If this true then s1 == s2 is true
Run Code Online (Sandbox Code Playgroud)
他的推理是有效的.但是,当我读到String.GetHashCode()时:
如果两个字符串对象相等,则GetHashCode方法返回相同的值.但是,每个唯一字符串值都没有唯一的哈希码值.不同的字符串可以返回相同的哈希码.
我想你知道我要去哪里.我想是我错过了什么,如果有的话,请指出我正确的方向.
谢谢!