Direct2D桌面窗口类模板基于ATL的CWindowImpl

时间:2015-07-26 13:49:50

标签: c++ templates c++11 atl direct2d

Kenny Kerr在他的Direct2D教程(part1part2)中展示了如何制作一个简单的2D动画时钟并使用以下类层次结构:

//Desktop window class based on ATL's CWindowImpl
template <typename T> struct DesktopWindow :
CWindowImpl<DesktopWindow<T>, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>>
{
    // code here, including:
    void Run() {}
};

//ClockSample class which further extends DesktopWindow
template <typename T> struct ClockSample : T
{
    //code here
};

//SampleWindow class which is empty and is needed, as far as I understand,
//to, so to speak, "untemplate" ClockSample template
struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>>
{
    //empty
};

//main function
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    SampleWindow window;
    window.Run();
}

我没有包含实际代码,因为它很大并且与问题无关。

struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>> - 我很难理解哪个类继承了哪个类,这里​​有什么? SampleWindow继承自ClockSample,然后又有SampleWindow,它看起来像是对我的循环引用?如果有人能用简单的话来解释这里到底发生了什么,我会很高兴。

1 个答案:

答案 0 :(得分:1)

SampleWindow继承自ClockSample(&#34; untemplates&#34;),后者又来自DesktopWindow,而CWindowImpl则来自ATL&#39; s CWindow(还有CWindow作为基类; HWNDSampleWindow窗口句柄上的瘦包装器。

template <typename T> struct DesktopWindow : CWindowImpl<DesktopWindow<T>, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>> { // code here, including: void Run() { T* pT = static_cast<T*>(this); // T = SampleWindow pT->InternalRun(); } }; struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>> { VOID InternalRun() { // So we eventually reach here } }; 作为模板参数允许&#34; downcast&#34;在代码中使用后代类并调用重写方法而不使用虚拟方法。这种方法特别在ATL中大量使用。

例如:

library(tm)
library(SnowballC)
corp <- Corpus(DirSource("/home/dataset/"), readerControl = list(blank.lines.skip=TRUE));  ## forming Corpus from document set 
corp <- tm_map(corp, stemDocument, language="english")
dtm <- DocumentTermMatrix(corp,control=list(minwordlength = 1)) ## forming Document Term Matrix
dtm_tfidf <- weightTfIdf(dtm)
m <- as.matrix(dtm_tfidf)
norm_eucl <- function(m) m/apply(m, MARGIN=1, FUN=function(x) sum(x^2)^.5)
m_norm <- norm_eucl(m)

kmax = 50

totwss = rep(0,kmax) # will be filled with total sum of within group sum squares
kmfit = list() # create and empty list
for (i in 1:kmax){
  kclus = kmeans(m_norm,centers=i,iter.max=20)
  totwss[i] = kclus$tot.withinss
  kmfit[[i]] = kclus
}

kmeansAIC = function(fit){

  m = ncol(fit$centers)
  n = length(fit$cluster)
  k = nrow(fit$centers)
  D = fit$tot.withinss
  return(D + 2*m*k)
}
aic=sapply(kmfit,kmeansAIC)
plot(seq(1,kmax),aic,xlab="Number of clusters",ylab="AIC",pch=20,cex=2)


kmeansBIC = function(fit){

  m = ncol(fit$centers)
  n = length(fit$cluster)
  k = nrow(fit$centers)
  D = fit$tot.withinss
  return(D + log(n)*m*k)
}
bic=sapply(kmfit,kmeansBIC)
plot(seq(1,kmax),bic,xlab="Number of clusters",ylab="BIC",pch=20,cex=2)